flypig.co.uk

List items

Items from the current list are shown below.

Blog

6 Nov 2023 : Day 82 #
Okay, so I managed to get to the bottom of why the browser was failing to start at all.

This was the problem I was experiencing yesterday. To recap, I'd made edits to the code to adjust the way the EglDisplay is handled. I created a package overnight, transferred it over to my phone and ran the updated version. The browser dropped out before it had even reached the code I edited.

The browser was exiting cleanly so there was no backtrace to dig into. I tried stepping through the code but the debugger seemed to exit before the main had properly even started. I thought it might be the code that attempts to load the libxul.so library, but the debugger showed that wasn't being reached either.

Eventually I gave up and decided to do a full recompile of the library and the libraries that depend on it. As always the full rebuild took hours. I started it last night and it was still running well into my work day this morning.

It did eventually complete without errors. Installing and running it on my device... had no effect. Same problem.

So I rebuilt qtmozembed and installed that. Same problem.

I thought it might have been a dirty configuration folder, so I deleted ~/.local/share/org.sailfishos/browser. Not that.

So my last ditch attempt was to rebuild sailfish-browser as well. But that didn't fix it either.

Eventually I realised the reason: there was an old sailfish-browser process still running in the background. If you try to run the browser and it finds a copy of itself already running, rather than open a second browser showing a URL it will send a DBus message to the incumbent executable asking it to open the URL instead, then bail.

So that's what was happening. I found this out when I attempted to use the debugger on main() again. This time I was able to step into the application and got as far as the debug message being sent in on line 121 of the sailfish-browser/apps/browser/main.cpp file:
    BrowserService *service = new BrowserService(app.data());
    // Handle command line launch
    if (!service->registered()) {

       [..]

        QDBusConnection::sessionBus().asyncCall(message);
        if (QCoreApplication::hasPendingEvents()) {
            QCoreApplication::processEvents();
        }

        return 0;
    }
After using kill on the process the new version started up just fine. So I probably could have avoided all that rebuilding if I'd just noticed this first.

No matter, at least it's running now and I'll know for the future.

Having said that, it's still exiting early. But at least it is now getting to the code I changed.

You may recall from previous posts that the key method I'm editing looks like this:
already_AddRefed GLContextProviderEGL::CreateWrappingExisting(
    void* aContext, void* aSurface, void* aDisplay) {
  if (!aContext || !aSurface) return nullptr;

  nsCString failureId;
  const auto lib = gl::DefaultEglLibrary(&failureId);
  if (!lib) {
    gfxCriticalNote << "Failed[3] to load EGL library: " << failureId.get();
    return nullptr;
  }
  bool result = lib.operator->()->Init(false, &failureId, aDisplay);
  if (!result) {
    gfxCriticalNote << "Failed[3] initialise display: "
                      << failureId.get();
    return nullptr;
  }
  const std::shared_ptr egl = 
    lib.operator->()->DefaultDisplay(&failureId);

  if (!egl) {
    gfxCriticalNote << "Failed[3] to create EGL library  display: "
                    << failureId.get();
    return nullptr;
  }

  [...]

  return gl.forget();
}

I've been fixing up the Init() call you can above, so that it now calls GLLibraryEGL::CreateDisplay(). I've changed it so that you can enter an aDisplay parameter of type EglDisplay which it will store, rather than trying to create its own. This is important because the display used for rendering needs to be created by qtmozembed and passed in, rather than being created by gecko.

What I hadn't realised is that gl::DefaultEglLibrary(), which you can also see above, also calls this Init() method. But because it doesn't pass in any aDisplay value, this gets set to zero and the code I added now returns early with the failure flag set.

To address this I've now edited the method above to avoid it calling gl::DefaultEglLibrary(). Instead it constructs it directly, like this:
already_AddRefed GLContextProviderEGL::CreateWrappingExisting(
    void* aContext, void* aSurface, void* aDisplay) {
  if (!aContext || !aSurface) return nullptr;

  nsCString failureId;
  const RefPtr lib = new GLLibraryEGL;
  if (!lib) {
    gfxCriticalNote << "Failed[3] to load EGL library";
    return nullptr;
  }
  [...]
I'm hoping that by making this change the Init() call that happens a few lines later will now complete without error.

It's nearly rebuilt, so soon I'll be able to check.

[...]

This time copying the 2770 MiB library over to my phone took longer than actually building it. But when I run the browser with the new library I experience the same problem. So this will need a little more work tomorrow to get it working.

For all the other entries in my developer diary, check out the Gecko-dev Diary page.

Comments

Uncover Disqus comments