Lwjgl3: SIGSEGV on macOS AARCH64 during GLFW error callback setup

Created on 9 Mar 2021  路  10Comments  路  Source: LWJGL/lwjgl3

Environment

  • LWJGL version: 3.3.0
  • LWJGL build #: 7
  • Java version: 15
  • Platform: macOS
  • Module: core

Description

Consider this mavenized HelloWorld app, depending on native-macos-arm64 LWJGL3 natives. When ran on macOS Big Sur, on a MacBook Pro Apple Silicon, using Azul JDK 15 AARCH64 (so it runs natively), LWJGL3 crashes when setting up the GLFW binding, namely the error callback via libffi. See this crash log for the full stack trace and system info.

Notably, before the callbacks are setup, the jemalloc binding is initialized, printing the following info:

<jemalloc>: Unsupported system page size
<jemalloc>: Unsupported system page size

I haven't looked into the sources yet, but I guess something in LWJGL or libffi makes assumption about the standard page size, usually assumed to be 4k. However, that is not true on macOS AARCH64. The page size needs to be polled from the OS.

Further more, if libffi or LWJGL setup trampolines via dynamically allocated executable memory on AARCH64, that memory has to be page aligned as well.

I'm unsure if you have the hardware to test things on. I'd be happy to help if instructed on how to do that.

Bug

All 10 comments

Upon some debugging, the call to allocator.malloc() in APIUtil. apiCreateCIF() returns 0.

Played with the latest jemalloc release. Looks like the configure script for jemalloc determines an incorrect value for LG_PAGE in your build, which is then set as PAGE in include/jemalloc/internal/pages.h.

PAGE is then compared to the return value of os_page_detect() in pages.c and that fails, which means subsequent allocations also fail, as the pages initialization is not completed.

On my MacBook Pro M1, configure sets LG_PAGE as follows:

checking LG_PAGE... 14

Which means PAGE is 16384. That's also what os_page_detect() returns. Running the jemalloc test suite on my M1 machine thus works as intended.

I assume you configure jemalloc once and reuse the value of LG_PAGE across platforms. That does not work for M1, or ARM in general, as page sizes are bigger than on x86-64 usually. To fix this, you'll likely have to configure jemalloc on each platform. I'm not super savy on LWJGL3's build system, so I leave that to you :)

Does it work if you use -Dorg.lwjgl.system.allocator=system?

Yes, that works, but then glfwInit() blocks indefinitely.

I'm an idiot and forgot -XstartOnFirstThread. Works as intended with the stdlib allocator.

A new jemalloc binary is up, built --with-lg-size=14. Could you please verify that it works? Download anywhere and use -Dorg.lwjgl.system.jemalloc.libname=<path> to point to it.

I can run the HelloWorld sample natively on M1 with this binary. The fixed 16Kb page size is likely to work the next few M1 iterations :)

Thanks Mario!

Hey, I am having the exact same issue, but don't know where to add the -Dorg.lwjgl.system.jemalloc.libname= part, I tried just adding it as a CLI argument in IntelliJ Idea, but it is not working. I already downloaded the new jemalloc binary and tried pointing to it, I just don't know where to add the actual pointing argument

I tried just adding it as a CLI argument

It should be a VM argument. In Intellij, open the run configurations window and click 'modify options' and select 'add vm options.'

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Theikon picture Theikon  路  5Comments

benalexau picture benalexau  路  4Comments

Marcono1234 picture Marcono1234  路  3Comments

Hugobros3 picture Hugobros3  路  7Comments

shathor picture shathor  路  3Comments