Package: libc6
Version: 2.31-1
Severity: normal

I've encountered an odd bug in openarena (#966150) which I'm concerned
might be a glibc regression affecting other packages.

Some background: openarena is a game running on the ioquake3 engine
(main executable: /usr/lib/ioquake3/ioquake3). During startup, the engine
dlopens some modules, which implement the actual openarena game and UI.
One of those modules is uses mathematical functions from libm, but is not itself
linked to libm. At runtime (at least on older systems) it works as
intended, because the ioquake3 executable *is* linked to libm. I'm aware
that this is not the most robust setup, and would ideally be
linked with -lm to make it self-contained; but it's documented as being
expected to work, and has always worked in the past:

    Symbol references in the shared object are resolved using (in order):
    symbols in the link map of objects loaded for the main program and its
    dependencies; [... and some more places ...]
    — dlopen(3)

The bug (#966150) is that a version of compiled with a slightly
older (2020-02-18) toolchain fails to load on an up-to-date sid system, with:

    undefined symbol: __atan2_finite

If I recompile openarena in a sid chroot, *with no source code changes*
(in particular is still not linked to -lm!), then it starts
to work again. The recompiled has an undefined reference
to atan2, but no reference to __atan2_finite any more.

I'm going to address this in bullseye by making openarena more robust
(explicitly linking to -lm). After I've done that, the updated version of
openarena will not be suitable as a reproducer for this bug report, but
the buster version of openarena will still be suitable.

If you believe this is not a significant regression in glibc and should
only be fixed by changes in openarena, I have no problem with doing that
and just closing this bug report. However, I wanted to raise this in
case it affects other previously-built binaries.

This can be reproduced somewhat conveniently as follows:

* Have a buster virtual machine
* Install openarena and enough of a desktop to get a terminal in an X11
* Run openarena
    * It succeeds
    * To exit quickly: Shift+Escape, type "/quit", Enter
* Add a bullseye apt source and "apt update", but do not upgrade everything
* Upgrade libc6 from 2.28-10 to 2.31-1, while upgrading as few other
  packages as possible
    * I used aptitude, which made me also upgrade gcc-9 and related
      packages, removing gcc-8
* Run openarena
    * It fails as described in #966150
* Downgrade libc6 and closely-related packages from 2.31-1 to 2.28-10
    * In my case this meant downgrading libc-dev-bin, libc6-dev, libc6
      and libc-bin, and removing libcrypt-dev and libcrypt1
* Run openarena
    * It succeeds again, confirming that this was a glibc behaviour change

I've been trying to put together a standalone reproducer that only uses
libdl and libm, but so far I have not been successful.

I believe this is related to a change in the representation of
the __atan2_finite symbol, which is used (at least by versions of
openarena compiled against older glibc) because openarena is compiled
with -ffast-math. In 2.28-10, that symbol was not hidden:

$ objdump -Tx /lib/x86_64-linux-gnu/
0000000000028280 g   iD  .text  0000000000000046  GLIBC_2.15  __atan2_finite

In 2.31-1, it is hidden, and there is no non-hidden definition (default

$ objdump -Tx /lib/x86_64-linux-gnu/
000000000002a1e0 g   iD  .text  0000000000000049 (GLIBC_2.15) __atan2_finite

Because is not directly linked to -lm, it has an undefined
reference to __atan2_finite with no particular version:

$ objdump -Tx /usr/lib/openarena/baseoa/pak6-patch088/
0000000000000000      D  *UND*  0000000000000000              __atan2_finite

As far as I can work out, this unversioned undefined reference can be
satisfied by __atan2_finite@@GLIBC_2.15 in the global namespace from
the old libm, but not by the hidden version __atan2_finite@GLIBC_2.15
in the new libm.


Reply via email to