Erlang NIFs. Unsupported file layout. Why?

Hello all!

Got problem with deploying prebuilt applications that is using NIF.
My application build on VBox virtual machine undef FreeBSD OS. When distributing on other VBox machines all is working. When distributing on physical server have troubles:

(test@001.test.service)2> exec:start().
exec: /usr/local/lib/erlang/lib/erlexec/priv/x86_64-unknown-freebsd14.0/exec-port: Exec format error
                                                                                                    {error,{port_exited_with_status,126}}
(test@001.test.service)3> =CRASH REPORT==== 11-Oct-2024::15:46:01.357352 ===
  crasher:
    initial call: exec:init/1
    pid: <0.93.0>
    registered_name: []
    exception exit: {port_exited_with_status,126}
      in function  gen_server:init_it/6 (gen_server.erl, line 835)
    ancestors: [<0.91.0>]
    message_queue_len: 1
    messages: [{'EXIT',#Port<0.7>,normal}]
    links: []
    dictionary: []
    trap_exit: true
    status: running
    heap_size: 2586
    stack_size: 28
    reductions: 2114
  neighbours:

It’s happening with Erlexec project GitHub - saleyn/erlexec: Execute and control OS processes from Erlang/OTP
When trying to use this project GitHub - ArboreusSystems/arboreus_library: The library for developing distributed Erlang applications having this troubles:

(test@001.test.service)1> a_time_now:microseconds().
=WARNING REPORT==== 11-Oct-2024::15:45:34.402367 ===
The on_load function for module a_time_now returned:
{error,{load_failed,"Failed to load NIF library: '/usr/local/lib/erlang/lib/arboreus_library/priv/a_time_now.so: unsupported file layout'"}}

This applications added to Erlang ‘lib’ folder by symlinks to another locations.
The folders schema totaly the same like on VBox machines, it’s everything identical.
How to fix it?

The system setting totaly identical it’s distributed with Rex/Perl automation procedures. No any manual settings added.

The file command showing this:

$ file /usr/local/lib/erlang/lib/arboreus_library/priv/a_time_now.so
/usr/local/lib/erlang/lib/arboreus_library/priv/a_time_now.so: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 14.0 (1400097), with debug_info, not stripped

Everything compiled with Rebar3. The modules that not using NIFs working perfectly.

Error code 126 is usually missing unix permissions, like file is not executable by user, or on a filesystem without exec permissions. If you’re deploying as a release, this should be correct when the release tarball is unpacked.

Check that first, if not, perhaps this helps:

Either way, is it erlexec that fails, or is it the process that erlexec spawns? What does running the spawned process manually do? does it work by itself? What signal does it exit with?

Its possible that the deployed h/w is missing CPU instructions (like AVX2 or similar) and your pre-built version is on a more modern CPU type.

More generally if the NIF fails to load I’d expect either:

  • incorrect architecture (build on arm64 but trying to deploy to x86_64)
  • missing dependencies
  • different runtime in deployed system

Post uname -a and pkg info |grep erlang on working & failing machines, maybe that shows what’s missing, and check cpu flags in dmesg on both boxes.

if you have a minimal project, that generates a release, and still fails, please share that.

1 Like

The cause of trouble were in i386 FreeBSD version. The Server Administrator, because of his own reasons decided to use 32bit version on server with 64bit architecture. From my side were organized automation and build system on amd64 version of FreeBSD (64bit) and that were the difference. On my question about why he did it in 2024, got reply that Erlang equipped with C++ NIFs is 32bit language … It made me loosing any abilities to say anything …

Problem solved … Reinstalling whole environment with FreeBSD amd64 version.