Noticed that compiling OTP with kerl or from the source binaries (elf files) are built with the debug info - is that intentional?

Hello,

Compiling the OTP either with kerl or from the source I noticed that binaries (elf files) are built with the debug information and are not stripped. It makes them quite big. Is that intentional? I mean wouldn’t default be just optimized binary without the debug information?

I noticed it because previously I used Erlang Solutions’ provided installations (for CentOS) and the binary files there are free from the debug information and are stripped.

I was looking for configuration options, but I failed miserably.

Here is a sample from the latest OTP:

file /usr/local/lib/erlang/erts-13.1.3/bin/beam.smp
/usr/local/lib/erlang/erts-13.1.3/bin/beam.smp: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=be8c0b6d161441fff42012f14461ef058c61b5e5, with debug_info, not stripped

And here is some old release installed from Erlang Solutions:

file erts-11.2.2.4/bin/beam.smp
erts-11.2.2.4/bin/beam.smp: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=d989fd155818e2c602f0dc74a902276ad137771f, stripped

Greetings,
pickme467

2 Likes

The Autoconf toolchain default to using “-O2 -g” as CFLAGS, which means that Erlang and all systems that use Autoconf (which is a lot of systems) also include debug information by default.

To remove the debug info you can set the CFLAGS variable to “-g” when running configure, or you can strip the executables after the fact.

2 Likes

Thank you for the answer.

Meanwhile I dug the configurations and compiled without debug for my use.

I also checked the official Erlang docker image. It doesn’t change default which means it’s quite a big image. I thought that maybe for containers the build procedure is different since container world strives for small images.

If that’s intendend then I’m ok with that.

I’m not that aware of Autoconf toolchain and I’m not sure how many of Erlang developers is, so maybe it would be good to describe it in the install manual in more explicit way (Erlang -- Building and Installing Erlang/OTP)? There is a section called “How to Build a Debug Enabled Erlang RunTime System”, which was kind of misleading to me, because I thought that it is about the debug version of the RunTime system (elf binaries). Since I wasn’t interested in the debug version I thought that the non-debug version is just free from any debug information. A section called “How to Build a Non-Debug, Small and Optimized Erlang RunTime System” might be a good symmetric section that would clear up this area.

1 Like

The Official image has quite a few use cases - which might include wanting debug, and it is pretty easy to strip out after the fact for those that don’t.

If you’re wanting small containers - there is an escript that will strip binaries that is part of a GitHub action to build minimal BEAM containers from scratch (which uses the Official image as a build stage). It should be pretty easy to “strip” out if you’re using another CI system. The resulting containers just have a stripped Erlang runtime with only the dependent shared libraries without a shell - original motivation background here.

1 Like

Stripping is just a way to remove debug information. But as far as I know debug information doesn’t get along with the optimization applied to the code. I’m not sure what are defaults for the official release, but I know that for my production docker I want a small footprint and a good performance. So to me it would be a better approach to control not only debug information but also generated code optimizations, thus the approach that involves autoconf mechanisms is more tempting to me.

I’m ok with tinkering, but I would like to know what is the “default”. That’s why I pointed to documentation as a nice solution of my issue.

1 Like

@pickme467 i’m also interested on how to build Erlang VM without debugging symbols with kerl.

1 Like

May be of help: https://github.com/kerl/kerl#enable-autoconf
Has an example of setting CFLAGS for the build

1 Like

@LeonardB does enabling KERL_USE_AUTOCONF=yes will overwrite the defaults (i.e drop the “-O2 -g”`?

1 Like

I’m realizing I meant to link to https://github.com/kerl/kerl#using-shell-export-command-in-kerlrc

This section shows you can use exported environment variables to set CFLAGS for the build
so if you just export CFLAGS="-O2 -g0" (or omitting the -g entirely) before the build you should have the result you’re looking for

(edited. an ‘-O’ value is required in CFLAGS)

I’m currently doing a test with asdf/kerl to confirm it works and will edit with results

2 Likes

Appears to work

$ export CFLAGS="-O2"
$ KERL_CONFIGURE_OPTIONS="--enable-smp-support --without-odbc --enable-kernel-poll --without-javac --enable-threads --enable-hipe --with-ssl"
$ asdf install erlang 23.3.4.18
asdf_23.3.4.18 is not a kerl-managed Erlang/OTP installation
....
Extracting source code
Building Erlang/OTP 23.3.4.18 (asdf_23.3.4.18), please wait...
....
Erlang/OTP 23.3.4.18 (asdf_23.3.4.18) has been successfully built
Cleaning up compilation products for 
Cleaned up compilation products for  under /home/leonard/.asdf/plugins/erlang/kerl-home/builds

$ objdump --syms /home/leonard/.asdf/installs/erlang/23.3.4.18/bin/erlc | grep debug
000000000001f20c l     O .bss   0000000000000004              debug

and a couple of previous builds (default "-O2 -g")

$ objdump --syms /home/leonard/.asdf/installs/erlang/23.3.4.14/bin/erlc | grep debug
0000000000000000 l    d  .debug_aranges 0000000000000000              .debug_aranges
0000000000000000 l    d  .debug_info    0000000000000000              .debug_info
0000000000000000 l    d  .debug_abbrev  0000000000000000              .debug_abbrev
0000000000000000 l    d  .debug_line    0000000000000000              .debug_line
0000000000000000 l    d  .debug_str     0000000000000000              .debug_str
0000000000000000 l    d  .debug_loc     0000000000000000              .debug_loc
0000000000000000 l    d  .debug_ranges  0000000000000000              .debug_ranges
000000000001f20c l     O .bss   0000000000000004              debug

$ objdump --syms /home/leonard/.asdf/installs/erlang/23.3.4.10/bin/erlc | grep debug
0000000000000000 l    d  .debug_aranges 0000000000000000              .debug_aranges
0000000000000000 l    d  .debug_info    0000000000000000              .debug_info
0000000000000000 l    d  .debug_abbrev  0000000000000000              .debug_abbrev
0000000000000000 l    d  .debug_line    0000000000000000              .debug_line
0000000000000000 l    d  .debug_str     0000000000000000              .debug_str
0000000000000000 l    d  .debug_loc     0000000000000000              .debug_loc
0000000000000000 l    d  .debug_ranges  0000000000000000              .debug_ranges
000000000001f20c l     O .bss   0000000000000004              debug

and size comparisons

$ ls -lah /home/leonard/.asdf/installs/erlang/23.3.4.*/bin/erlc
-rwxr-xr-x 1 leonard leonard 704K Jan  5  2022 /home/leonard/.asdf/installs/erlang/23.3.4.10/bin/erlc
-rwxr-xr-x 1 leonard leonard 704K May  6  2022 /home/leonard/.asdf/installs/erlang/23.3.4.14/bin/erlc
-rwxr-xr-x 1 leonard leonard 143K Jan 19 14:12 /home/leonard/.asdf/installs/erlang/23.3.4.18/bin/erlc

and finally

$ file /home/leonard/.asdf/installs/erlang/23.3.4.*/bin/erlc
/home/leonard/.asdf/installs/erlang/23.3.4.10/bin/erlc: ELF 64-bit .... for GNU/Linux 3.2.0, with debug_info, not stripped
/home/leonard/.asdf/installs/erlang/23.3.4.14/bin/erlc: ELF 64-bit .... for GNU/Linux 3.2.0, with debug_info, not stripped
/home/leonard/.asdf/installs/erlang/23.3.4.18/bin/erlc: ELF 64-bit .... for GNU/Linux 3.2.0, not stripped
2 Likes

That’s exactly what I did for my case. I just used CFLAGS. But I was afraid that maybe CXXFLAGS are also needed. It’s tricky to know exactly what to set, you need to know if the project compiles C++ or just plain C.

1 Like