Lazarus

Programming => Operating Systems => Linux => Topic started by: fedkad on March 28, 2022, 03:59:03 pm

Title: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: fedkad on March 28, 2022, 03:59:03 pm
I am running "Lazarus 2.2.0 / FPC 3.2.2 / x86_64-linux-gtk2" on Ubuntu 21.10. The code compiled under this environment, when attempted to be run on a slightly older (but, still supported) version of Linux, for example Debian 10 will give an error like this:

./my_program: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./my_program)

How can I create Linux executable code that can be run on any version of GLIBC smaller than 2.34?

Note: "objdump -T my_program | grep -i glibc" output is something like this:

0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 wcrtomb
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 wcscoll
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.34  dlerror
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 setenv
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 setlocale
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 strcoll
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.34  dlopen
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 iconv_close
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 mbrlen
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.34  dlclose
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 mbrtowc
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.34  __libc_start_main
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.34  dlsym
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 iconv
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 iconv_open
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 nl_langinfo
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 towlower
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.34  dladdr
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 __errno_location
0000000000000000      DF *UND*   0000000000000000  GLIBC_2.2.5 towupper
0000000000000000  w   DF *UND*   0000000000000000  GLIBC_2.2.5 __cxa_finalize
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: trev on March 28, 2022, 04:07:18 pm
The obvious answer is to statically link the needed libraries rather than loading them dynamically. The most significant advantage of static linking is that the application can be certain that all its libraries are present and that they are the correct version. Static linking of libraries also allows the application to be contained in a single executable file, simplifying distribution and installation. Also with static linking, only those parts of the library that are directly and indirectly referenced by the target executable are included in the executable. With dynamic libraries, the entire library is loaded, as it is not known in advance which functions will be used by the application.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on March 29, 2022, 10:24:04 am
How can I create Linux executable code that can be run on any version of GLIBC smaller than 2.34?

By compiling it on a system that has an older GLIBC. This is simply how things work on Linux or ELF files in general. See also Jonas Maebe's answer here (https://gitlab.com/freepascal.org/fpc/projects/-/issues/3#note_892374986).
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: fedkad on March 29, 2022, 10:31:33 am
Thanks for the answers. I was expecting a compile and/or link option that will prevent the usage of GLIBC 2.34.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Gustavo 'Gus' Carreno on March 29, 2022, 11:07:54 am
Hey Fedkad,

Thanks for the answers. I was expecting a compile and/or link option that will prevent the usage of GLIBC 2.34.

I've had the same issue since I'm also in Ubuntu 21.10 and I've noticed this quite a while ago.

I'm not sure the lower version `libc` is still installed in the system since I never bothered to actually go look, but if it still is, due to some relic binary that cannot link to 2.34, there could be a solution.

The solution I've thought about is to do with messing around `fpc.cfg` to have `libc` served from another folder.
I'm not quite sure if this is possible, since it would have to be passed to the lnker, but if possible, this would solve the problem.

In any case, this would be a case for the more experienced Free Pascal users on this forum to pitch in and give some suggestions of the if its possible OR how to go about it.

Cheers,
Gus
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on March 29, 2022, 11:22:55 am
Seems strange, I build my app on an U20.04 VM and it has libc6 2.31 and the resulting binary works fine on U16.04 and its a lot older 2.23 libc6.  Thats a far bigger jump than fedkad mentions.

Is there some more significant change taken place with 2.34 ?

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on March 29, 2022, 01:24:06 pm
Is there some more significant change taken place with 2.34 ?

Yes, there is. They changed how the initialization (https://sourceware.org/git/?p=glibc.git;a=commit;h=035c012e32c11e84d64905efaf55e74f704d3668) works and thus an older libc with binaries compiled for a newer libc would lead to possibly hard to debug problems, because the initializers and finalizers of the binaries wouldn't be run.

The last change with a versioned symbol was with 2.1, though that probably wouldn't affect FPC and then 2.0 which would affect FPC (thus you can't use a FPC compiled binary compiled on a system with a glibc < 2.34 with a glibc older than 2.0).
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on March 30, 2022, 12:36:09 am
Hmm, I am not sure DP's explanation explains fedkad experience here though.

Debian Buster was updated to 2.28 recently (March 22) and that should work fine.

fedkad, is your Buster test system up to date ?

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: fedkad on March 30, 2022, 10:43:37 am
fedkad, is your Buster test system up to date ?

No. I tested my executable at: https://distrotest.net/Debian
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on March 30, 2022, 10:56:38 am
I would recommend Virtual Box, only real downside is diskspace used by all the VMs you end up keeping.

And, maybe, a VM to build your application too ?  Thats how I work, I have a Bullseye VM where I build the SRC Debs for Debian and a U20.04 VM where I build my binary distributions, its setup to cross compile so I can make 64 and 32 bit Linux, (Debs and RPMs), Win32, RaspPi ....

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: RDL on May 13, 2022, 12:51:08 pm
@fedkad
Check my ticket on fpc gitlab
https://gitlab.com/freepascal.org/fpc/projects/-/issues/3
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on May 13, 2022, 02:52:41 pm
Noting what everybody else has said, but I believe that the fundamental issue is that the linker resolves/follows symlinks so the actual filename in the executable is that of the actual library.

I don't believe that's fixable, it's quite simply the way that the linker and loader work on Linux (and possibly other unices).

I've definitely seen comparable issues, although I can't recall whether they specifically involved (g)libc. Also I can't say whether they apply to unices other than Linux, since I've rarely (if ever) had multiple versions of these running and in any event it's long been my policy to try to have FPC/Lazarus on representatives of all OS variants and versions.

A related problem I had a couple of years ago was due to an ALSA version change. I worked around that by putting Docker on my development system and setting up a container with the target OS such that I could ssh in and get a shell, after which I could run Lazarus and FPC in the normal way.

So I suggest that the first thing to do is to follow through the symlink chain on both systems. I'd be very happy to be told I was wide of the mark, and that there was a simpler fix :-)

Added: If it is a library naming issue, it might be possible to fix it using patchelf

http://manpages.ubuntu.com/manpages/bionic/man1/patchelf.1.html

I've not experimented with this, and I don't know what would happen if a symlink name was patched into the ELF header.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on May 16, 2022, 01:27:26 pm
Noting what everybody else has said, but I believe that the fundamental issue is that the linker resolves/follows symlinks so the actual filename in the executable is that of the actual library.

It's not an issue with symlinks or the name of the library. The issue is that newer libcs have a versioned symbol and according to the ELF spec when a symbol that has a version attached is used then this needs to be referenced as such in the ELF binary so that the dynamic linker can then resolve this using the correct version of the symbol, this implicitly also means that if you try to run a binary that uses such a versioned symbol on a system where the corresponding library does not have this symbol with the suitable version (or none at all) then the binary simply won't load. It's as if you'd use a symbol that doesn't exist at all.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: abouchez on September 27, 2022, 08:24:54 am
Old Thread, but perhaps something was overseen.

The error states that dlopen/dlsym/dlclose are not available in the libc/'c'.
And they should not, because on Linux they are part of libdl/'dl' as stated by rtl/unix/dl.pp

My guess is there is something wrong somewhere in your code or its dependency, which define dlopen/dlsym/dlclose manuall as external 'c'.
Perhaps try to use the unit dl which defines things as expected.

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on September 27, 2022, 08:27:53 am

WOW, unbelievable !  This thread is many months old and we had a clash. abouchez, maybe my summary will help ?

OK, so its an old thread but still a problem.
I thought I'd summarize where we are at !

The issue as we know is that, on Linux system, binaries compiled on a system with glib6-2.34 or later will not work on systems using an earlier glibc6. These Ubuntu and Debian distros use the following glibc6 -

* U20.04  - 2.31   
* U21.04  - 2.33
* U21.10  - 2.34  (Impish)
* U22.04 -  2.35  (Jammy)

* D.Bullseye - 2.31
* D.Bookworm - 2.34

If you build your app on Ubuntu Jammy or Impish or on Debian Bookworm it will not run on a number of still currently supported systems. I am talking here about Ubuntu and Debian but obviously, same situation applies for all the other distributions !

To my surprise, a build on Jammy works fine on Impish so its a one off problem, not ongoing.

I, personally, will keep a Ubuntu 20.04 system going to use as a build machine for the packages I distribute directly, they will run everywhere and I can have a current FPC/Lazarus on them.

But I also distribute through an Ubuntu PPA, there you must use the FPC/Lazarus provided by the target release or build newer ones from a source package. Ubuntu, Bionic, U18.04 for example has Lazarus 1.8 and is still an officially supported release until April 2023.

I have in the past ported Lazarus 2.0.10 and FPC3.0.2 from Debian Backports to a PPA but really don't want to do that again, because Debian break these up into tiny little modules, its just too messy.

I assume the really good Lazarus and FPC debs distributed through SourceForge are built as binaries from the start, not as source packages ?  If source, they could be pushed to a PPA ...

Sigh ....

Anyway, there it is, if you build and distribute binaries to other Linux users, beware !


Davo


Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on September 27, 2022, 09:01:05 am
The error states that dlopen/dlsym/dlclose are not available in the libc/'c'.

There is no mention of dlopen, dlsym or dlclose as part of the error. The only time they're mentioned here is in the listing of the unresolved symbols of the binary in the first message and there that is normal.

My guess is there is something wrong somewhere in your code or its dependency, which define dlopen/dlsym/dlclose manuall as external 'c'.
Perhaps try to use the unit dl which defines things as expected.

*sigh* It has nothing to do with these symbols, but with the symbol versioning of the C library. This was already solved.

Anyway, there it is, if you build and distribute binaries to other Linux users, beware !

This! ;D (except if they're statically linked like the FPC compiler binary itself ;) )
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on September 29, 2022, 12:33:26 am
Hello.

For info: https://packages.debian.org/search?keywords=libc6
For Debian (who knows, afaik, what is stable or not), version 2.31 is the last stable release.
2.34-2.35 are considered as unstable and 2.36 is experimental.

So if you want that your binary-release can run in lot of distros, better to compile+link with a stable libc.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on September 29, 2022, 02:15:29 am
2.34-2.35 are considered as unstable and 2.36 is experimental.
Yes Fred but consider that with Ubuntu, arguably the most used distro, the 22.04 long term release, already 5 months old, is using 2.35, that means that all the Ubuntu derivatives such as Linux Mint are also using 2.35 !  The cat is well and truly out of the bag !

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: stephanie on October 02, 2022, 10:59:43 am
Hello,

I have the same problem. I've Lazarus both on a Debian 10 Buster, that uses glibc 2.28 and on a Xubuntu 22.04 LTS, that uses glibc 2.34.

If I compile on Xubuntu (glibc 2.34) the executable cant't run on Debian Buster (glibc 2.28):

Code: Pascal  [Select][+][-]
  1. stephanie@PcServer:~$ ldd /home/stephanie/MyErpNew/myerp_new_Laz224c
  2. /home/stephanie/MyErpNew/myerp_new_Laz224c: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /home/stephanie/MyErpNew/myerp_new_Laz224c)
  3.  

It seems it's always necessary to have a virtual machine with an older version of a Linux distro, in order to allow that the executable works on all version of Linux. Otherwise, if I compile with a new Linux distro, who has an older distro can't run the excecutable.

Of course I find unconfortable this, but I've found a better solution yet.

If anyone have an idea to bypass this problem, it would be very appreciated.

I hope that in the future Lazarus can improve a solution to this case.

Sorry for my bad English.

Best regards,

Stephanie
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: colo on October 02, 2022, 11:40:43 am
You don't really need a complete virtual machine around for this; a chroot environment (or "container") suffices. I keep a systemd-nspawn container with Debian oldstable in it (and a recent Lazarus installed from upstream-provided Debian packages) around to build executables with that will run on rather dated GNU/Linux environments, too.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: stephanie on October 02, 2022, 11:53:47 am
Thank you for your reply.

How could I configure a chroot environement? Where could I find documentation? I've no experience with this.

Thank you again, best regards,

Stephanie
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on October 02, 2022, 12:17:06 pm
...
I hope that in the future Lazarus can improve a solution to this case.


The best solution would be that fpc does not need to link libc.so for his /rtl/.
But this is not for soon (afaik).
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: colo on October 02, 2022, 01:56:47 pm
Thank you for your reply.

How could I configure a chroot environement? Where could I find documentation? I've no experience with this.

Thank you again, best regards,

Stephanie

Assuming you use a Debian-based distribution (such as Ubuntu) to develop on, you can install a package named debootstrap. This software can spawn complete Debian (and a number of derivatives) installations into another directory on your currently mounted file system. The Arch Linux wiki has an excellent article on this technique, which is applicable to an Ubuntu host: https://wiki.archlinux.org/title/Systemd-nspawn#Create_a_Debian_or_Ubuntu_environment

The debbostrap documentation will tell you how you can set up Debian 9 or Debian 10 inside such a deboostrap directory, which you can then use to start that as a container via systemd-nspawn. If you want to run a complete Lazarus environment inside that Debian container, with access to its GUI, check out https://wiki.archlinux.org/title/Systemd-nspawn#Use_an_X_environment (which is kinda advanced, but also not necessary).

You will also want to access the Lazarus project files from your current develpment environment in the container, and for that you will have to map paths from host to container. https://wiki.archlinux.org/title/Systemd-nspawn#Access_host_filesystem touches on that.


My personal setup is an Arch Linux installation on my desktop computer, and I use Lazarus under my user account named "colo" there to develop applications. The source code is stored in /home/colo/codebase in that Arch Linux installation. I do have a Debian 10 Container in /var/lib/machines/deb10 (initially created via deboostrap), which also has a user account named "colo" created. To start and enter the container, I invoke `sudo systemd-nspawn -D /var/lib/machines/deb10 -b --bind=/home/colo/codebase/ --bind=/home/colo/.Xauthority --bind=/tmp/.X11-unix/` on my Arch Linux host, and log in to the Debian-based account on the login prompt that show up after that command succeeds. There, I can set the DISPLAY environment variable to point at my Xorg display on the host (export DISPLAY=:0.0) and use lazarus-ide from inside the container, or use lazbuild to create a new executable without having to use the GUI. The binaries end up in the directory shared between the host and the container. When I'm done, I shut down the container as if it were a real machine.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: stephanie on October 02, 2022, 09:04:19 pm
Thank you very very much!

Very interesting.

I'll study the documentaion and I'll try.

Thank you again, best regards,

Stephanie
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on October 03, 2022, 02:28:45 pm
I hope that in the future Lazarus can improve a solution to this case.

There is no better solution than to compile your application on a suitable, older distribution. Anything else is just a hack waiting to break at the most unwanted time possible.

...
I hope that in the future Lazarus can improve a solution to this case.


The best solution would be that fpc does not need to link libc.so for his /rtl/.
But this is not for soon (afaik).

Not linking to libc means no support for threads or linking to any other more involved library as the C library these libraries in turn depend on wouldn't be initialized correctly (as that is the task of the application startup code).
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: stephanie on October 03, 2022, 10:14:44 pm
Hello,

an AppImage might be a solution?

I don't know if there is an easy tool to generate a Linux AppImage from Lazarus.

An AppImage should have all dipendences in the unique file.

Anyone has tried?

Best regards,

Stephanie
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on October 04, 2022, 12:03:21 am
Hello,

an AppImage might be a solution?

I don't know if there is an easy tool to generate a Linux AppImage from Lazarus.

An AppImage should have all dipendences in the unique file.

Anyone has tried?

Best regards,

Stephanie

The quick, easy an safe way is to install Debian 10 Buster that uses libc.so.6 ver 2.28.
https://www.debian.org/releases/buster/debian-installer/

You may install the downloaded iso image with a server virtualization software like VMWare or VirtualBox or QEmu.

Then install on that virtual machine last fpc, last Lazarus and compile your last source (that you have developed on your main dev-machine an copy on a usb stick, loaded in the virtual machine).
An copy the compiled-result-binary and paste it in your release-package.

Your release will run on nearly all actual Linux distros.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: colo on October 04, 2022, 10:19:34 am
You could look at AppImage, Flatpak, Snap, and potentially other "modern" software distribution vehicles and mechanisms, but they come with a fair share of added complexity and responsibility. If you just dynamically link the host OS's libc, you don't have to keep track of that library's security issues in your distributed copy. So as long as you can get away without shipping a complete "runtime" set of userspace libs along with our application, I think it's wise to do so.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on October 04, 2022, 11:02:05 am
Hmm, I always have several, maybe 10 or 12 current VirtualBox machines on hand because you need to test your app with different desktops. So, my build machine is U2004 Gnome. Its a good idea to build (ie a final, release build) on a different system than you develop on, helps catch situations where your app depends on something that you just happened to have installed on your day to day machine.

And I need to test against Gnome and I'd never work, by choice, on a Gnome system.

AppImage ?  I looked at that awhile ago, got some very conflicting answers about a GTK2 based AppImage, somone answered my question about where it is only to have that answer removed and replaced by a "we don't do GTK2" - no further response.

Packaging containers are generally a real pain !  My App, tomboy-ng is about a 3Meg download and uses about 6meg of diskspace. It replaces the original Tomboy that you can still install as a Flatpack, its a 700Meg download and uses 2.4G of diskspace. Anyone want to guess how much RAM it uses when running ?

Another build model that might be useful if you already make debs to distribute your app (and its open source) is Ubuntu's PPA. Despite my grizzels above about having to work with a Debian deb of FPC/Lazarus, I have built an up to date PPA based on U2004 with FPC3.2.2 and Lazarus 2.2.2, if you can make a source package, welcome to use it to build (and distribute) your app.

Davo

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on October 04, 2022, 01:15:26 pm
an AppImage might be a solution?

I don't know if there is an easy tool to generate a Linux AppImage from Lazarus.

An AppImage should have all dipendences in the unique file.

That would also mean that you're responsible for maintaining all the libraries (and when you replace libc it really is all the libraries) and keeping them up-to-date. Not to mention the size issue as dbannon mentioned.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: stephanie on October 04, 2022, 02:03:45 pm
Hello,
thanks for your answers, they helped me a lot to understand better.
At this point virtualization with VirtualBox or using debootstrap is the best solution.
I was already using this solution, although sometimes vice versa, in the sense that I often test new versions of Lazarus on a virtual machine first before moving on to work on the updated version.
For example now I have a Debian Buster with Lazarus 2.0.4 on the host machine and a XUbuntu 22.04 with Lazarus 2.2.4 on the guest.
I just would have preferred to be able to test the executable generated on the guest on the host, but I understand that it is not possible and then I will test on the guest, no problem.
One last question: being Linux Open Source, couldn't you add some older version library packages, with an option to compile with them?
With Windows presumably it cannot be possible for licensing reasons, but with Linux it should perhaps be possible.
However now it is much clearer to me, thank you very much for your answers.
Best regards,
Stephanie
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on October 04, 2022, 02:42:18 pm
...
One last question: being Linux Open Source, couldn't you add some older version library packages, with an option to compile with them?

Not sure to understand but, apart for libc.so, you may use LoadLibrary(/path/of/library) (= dlopen()) instead of linking the library at compilation (using "external").
https://wiki.freepascal.org/Lazarus/FPC_Libraries#Loadlibrary_-_dynamically_loading_a_dynamic_library

And have the choice to load the library form where an when you want.

For example, this fpgui project dynamically loads X11 and TThreads dependencies:
https://github.com/fredvs/uidesigner_ext

 
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on October 05, 2022, 01:25:52 am
Another thing worth keeping in mind is that this is, hopefully, a one-off problem.
Over time, all the systems running <v2.34 will be updated and will work in a post 2.34 world.  I have tested the latest Ubuntu, it uses 2.35 and binaries made there work fine on a 2.34 system. Promising ...

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on October 05, 2022, 09:02:13 am
One last question: being Linux Open Source, couldn't you add some older version library packages, with an option to compile with them?

In theory, yes, but due to Linux favouring Open Source software: simply recompile the applications in question. Much less maintainance burden for the distribution developers.

Another thing worth keeping in mind is that this is, hopefully, a one-off problem.
Over time, all the systems running <v2.34 will be updated and will work in a post 2.34 world.  I have tested the latest Ubuntu, it uses 2.35 and binaries made there work fine on a 2.34 system. Promising ...

It's not a one-off problem, because it will surface every time the developers of the C library introduce a versioned symbol that's used by a program. In the case of 2.35 vs 2.34 they simply didn't introduce such a symbol or your program doesn't access the symbol in question.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: maxerist on November 19, 2022, 09:20:47 am
This is probably the longest thread about the topic, I'll add also my two cents. Please, correct me for everything I did wrong.

There's a program readelf and anyone can list any versioned glibc symbols in executables, so, o, a files with the following command
 
Quote
readelf -Ws {file} | grep GLIBC

you will see the lines ending with something like ".... pthread_mutex_destroy@GLIBC_2.2.5 (2)"
GLIBC_2.2.5 из the version (set) (abi) that was chosen by the linker, the number in parenthesis is the version of this symbol. So @GLIBC_2.8 (2) will mean that the later abi list was chosen (2.8) but actual version of the symbol is the same

The compiler (fpc in our case) don't use such versioned symbols, it's the linker who sees pthread_mutex_destroy and having glibc on this system with particular latest abi, chooses the @ ending.
We in pascal have already a feature to limit this. So if you declare the imported function like
 
Code: Pascal  [Select][+][-]
  1. pthread_mutex_destroy... external clib name 'pthread_mutex_destroy@GLIBC_2.2.5'

the linker will be content to follow. Only the abi set like here (2.2.5) should exist in the glibc version in the system.

Also note that if experimenting with linking particular versions there are some states when the symbol with invalid name might exist in compiled units, but linker doesn't care (for example with the declaration is implementation-only and not used inside the implementation section)

In classic c as long as I remember there's no syntax to use a different imported name for a function, but at least for gcc recently one can use symver macro. I successfully tested this preparing a special sqlite versions for static linking.

Code: C  [Select][+][-]
  1.   __asm__(".symver pthread_mutexattr_init,pthread_mutexattr_init@GLIBC_2.2.5");
  2.  

This is great (as long as correct set of functions are chosen) so for the units the end developer has in control, the changes can be made to compile on newer system for executable to work on older ones.

But there are also fpc and lazarus that might use glibc directly or indirectly. Create a simple lazarus form project and readelf it. You will get probably dozens of versioned glibc functions.

Also one of such cases if one creates absolutely new "simple program" having nothing in it and compiling into 200k executable. You readelf it, you won't find any glibc dependencies. But add dynlibs to uses section and you will get dlopen and several other dl... functions with version information (probably 2.34 for recent linux versions, since this glibc version is notable in that they merged different so modules to reside in the single libc so they have to do version increase for plenty of related functions). But the glibc binding is unexpected, the dl unit having dlopen declaration uses "dl" lib. Here we have an indirect consequence, it's probably the smart linker of recent versions who knows (or resolved with symbol chaining) that here it maps dl* function to newly reappeared ones in glibc. I also tried to make a vanilla case with a very simple program with a single simple dlopen import declaration pointing to dl (libdl) lib but the linker still took versioned glibc function for the imported symbol

So fpc (and probably lazarus also) formally distance themselves from the c runtime in most of basic cases (probably threads is another exception) but has no full control about it. But in case with acknowledge that investigation of basic glibc usage in fpc/lazaraus is possible then the capping might look like this

Code: Pascal  [Select][+][-]
  1.  
  2. {$ifdef ...}
  3.    glibc_ver_cap = '@GLIBC_2.2.5'
  4. {$else}
  5.    glibc_ver_cap =  ...
  6. ....
  7.     glibc_ver_cap =  '';
  8. {$endif}
  9.  
  10. pthread_mutex_destroy... external clib name 'pthread_mutex_destroy' + glibc_ver_cap;
  11.  
  12.  


But the road is probably difficult. I suspect for example for dl* functions that prior to some version before 2.34 there were no dl* symbols in glibc and everyone linked against libdl. So in some cases the name manipulating might involve not only the name of the imported symbol but also the name of the lib.

Probably compiling on a "minimum" system is still the golden rule for us. The minor issue here is that dealing with this I had to install rpm-based set on a CentOS 7 based system and ended up repacking fpc installer with the instructions found here in forum and elsewhere at the web. Probably the suggestion here is for future fpc installer not to use [ rpmlib(payloadiszstd) ] compression for easier installig in earlier linux versions.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on November 19, 2022, 10:35:33 am
@maxerist Thanks for that, I think you're the first person pointing out- certainly in this thread- the importance of the @ qualifier in an external declaration.

I usually wrap program-controlled dynamic linkage in a class, and when I have time I'll review that in light of what you're saying about different versions of libdl etc.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on November 19, 2022, 11:26:52 pm
Also one of such cases if one creates absolutely new "simple program" having nothing in it and compiling into 200k executable. You readelf it, you won't find any glibc dependencies.

The RTL links against the C library only when the used units require it. And the core units don't. That's why for threading support you need to add cthreads.

But add dynlibs to uses section and you will get dlopen and several other dl... functions with version information (probably 2.34 for recent linux versions, since this glibc version is notable in that they merged different so modules to reside in the single libc so they have to do version increase for plenty of related functions). But the glibc binding is unexpected, the dl unit having dlopen declaration uses "dl" lib. Here we have an indirect consequence, it's probably the smart linker of recent versions who knows (or resolved with symbol chaining) that here it maps dl* function to newly reappeared ones in glibc.

That is because the dl unit which is used by the DynLibs unit explicitly links against the C library:

Code: Pascal  [Select][+][-]
  1. {$if defined(linux)}
  2.     { if libc is not linked explicitly, FPC might chose the wrong startup code, as
  3.       libdl depends on libc on linux, this does not hurt }
  4.     {$linklib c}
  5. {$endif}

So fpc (and probably lazarus also) formally distance themselves from the c runtime in most of basic cases (probably threads is another exception) but has no full control about it.

For Lazarus not linking against the C library is not really possible, because it requires the use of C libraries be it GTK, Qt or - if one would do a custom drawn widgetset - against the X11 or Wayland libraries.

But in case with acknowledge that investigation of basic glibc usage in fpc/lazaraus is possible then the capping might look like this

We are not interested in introducing any kind of capping regarding the C library into the RTL. If you want your program to support a certain C library version then compile on a distribution with that version.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: maxerist on November 20, 2022, 06:39:39 pm
@MarkMLl, thanks for mentioning dynamic loading, if one has control of a unit with external declarations to glibc he or she can choose dynamic loading instead of static declarations and this can help with avoiding the problem with versioned symbols

@PascalDragon, thanks for clarifications and explaining the state of things at the moment. You added to my conviction that trying to implement full glibc version control is not feasible.

Also some additional observations. When we compile on a system with glibc version N, the question arises what is the minimum glibc version M when the program will start on a system with it and not complain about not founding some versioned symbol. The answer it depends... All info below is for Linux x86_64

It looks like For glibc 2.34 N = M = 2.34 in 99.999% cases. This is because the glibc team did a big thing finally merging (libdl libpthread libc libutil libanl) into one library and making some additional changes so finally many dl*, pthread* functions increased in version and even  __libc_start_main did. The latter is important because this is a symbol fpc magically control by itself and the end program developer has no control of it (PascalDragon will correct me is I'm wrong).

But for earlier version M < N for many cases. For example, I compiled a blank form Lazarus project on a system with 2.28 and it looked like all symbols were from 2.2.5. Another approach for guessing was when I collected all default symbols from 2.28 libs (libdl libpthread libc ...) with readelf ... | grep @@... and grouped the result list by count. The majority of public symbols (probably 90%) were from version 2.2.5, the next in charts were 2.3, 2.4, 2.3.4. So it depends on the functions used in the program.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on November 20, 2022, 06:53:33 pm
@MarkMLl, thanks for mentioning dynamic loading, if one has control of a unit with external declarations to glibc he or she can choose dynamic loading instead of static declarations and this can help with avoiding the problem with versioned symbols

Except that it /is/ relevant for access to libdl etc. itself.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: maxerist on November 24, 2022, 03:13:17 pm
Just would like to share a proof of concept approach for building the fpc/lazarus executable on another system with limited requirements (fpc/lazarus not required)

This will work becuase of the following observations:
But I should mention that this method involved some cheating unless fpc has or will have some option allowing working without one. Also the details about my experience will require adjustments with other project/configurations

Part 1. fpc/lazarus on any machine you prefer to develop with

During the compilation process fpc launches the linker (/usr/bin/ld ) to link all the required object files (o, a) into the executable. We will just learn how the compiles does this and reproduce it on another machine. The actual line involved can be seen if you check [ Verbosity-Show executable info (Win32 only) (-vx)  ] and after that either  "Copy all/Original messages to clipboard" to find it amongst them or  "Filter non-urgent message-None" and copy individual line
It should look something like
Quote
  "Debug: Executing "/usr/bin/ld" with command line "-b elf64-x86-64 -m elf_x86_64  --dynamic-linker=/lib64/ld-linux-x86-64.so.2     -L. -o {pathToTargetExeFile} -T {pathToScript} -e _start"

Here {pathToTargetExeFile} is to be modified or left as it is and {pathToScript} is important part that involves cheating.

All the paths to necessary files is in the script. All linked object files, search directories and so on. Normally this file (its name is something like link4372.res) is created by the compiler and deleted after linking.

But you can let it live with two alternative options:

The script contains several sections, but we're  interested in INPUT( and GROUP( ones with absolute pathes. Fpc does a great job introducing here all the correct absolute pathes to all required object (o) or library (a) pathes. In my case I even felt free to delete all the directories from the SEARCH_DIR section. The only exceptions were crti.o and crtn.o files whose pathes were wrong, I just fixed them.

So the steps involved in linking on another machines are:

Part 2. The OS/machine.

In my case I made the experiment with a fresh Debian 64 install. Currently (23.11.2022) it contains glibc 2.31 so compilable for glibc 2.31 and lower versions. For my project due to a singe symbol this was 2.28 (All other symbols were from 2.2.5).
There were requirements for successful linking

That's almost all, also just stripped the executable since it contained the debug symbols.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on November 24, 2022, 05:35:59 pm
I'd throw in (after a few minutes playing) that on Linux Lazarus Options -> Compiler Options -> Custom Options -> All Options ... gives you a checkbox for -sh (or you can just add that to the "Custom Options" list). Selecting that results in a build finishing with a ppas.sh script and a .res for the linker's -T option.

That has some useful implications for an issue I raised a couple of weeks ago where it wasn't possible to build FPC 3.2 using 3.0 on Linux x86_64, which the developers brushed under the carpet.

Another thing worth getting into the doctrine is that ld (GNU ld, particularly on Linux) resolves all symlinks, so moving a binary between systems with substantially different varianct of core libraries can be an issue.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: maxerist on November 25, 2022, 09:43:30 am
I'd throw in (after a few minutes playing) that on Linux Lazarus Options -> Compiler Options -> Custom Options -> All Options ... gives you a checkbox for -sh ....
Great to know, thanks.  I wish I knew, my post would be much shorter :)

I can confirm that for sh/st options the res file is exactly the same as the one that is created and deleted without it. Also the shell script generated by fpc works when executed on another machine (providing other necessary steps were made). It links and aslo extracts debug symbols (if necessary) and strips. The only difference I noticed between sh and st (shell for target linking) options is that latter uses the tool executable names without full paths, probably assuming that the tools locations might be different.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on November 25, 2022, 09:56:28 am
I can confirm that for sh/st options the res file is exactly the same as the one that is created and deleted without it.

I've not checked yet but expect differences in the .res file between 3.0.4 and 3.2.0, relating to the -T warning that appeared during a 3.0 compilation. That can have various side-effects, depending on target.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on November 27, 2022, 09:56:02 pm
I can confirm that for sh/st options the res file is exactly the same as the one that is created and deleted without it. Also the shell script generated by fpc works when executed on another machine (providing other necessary steps were made). It links and aslo extracts debug symbols (if necessary) and strips. The only difference I noticed between sh and st (shell for target linking) options is that latter uses the tool executable names without full paths, probably assuming that the tools locations might be different.

-sh -> Script for linking on host
-st -> Script for linking on target

That's why there are differences.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on November 27, 2022, 11:06:00 pm
-sh -> Script for linking on host
-st -> Script for linking on target

That's why there are differences.

Sorry, I should have spotted that and saved you some work.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: c600g on December 02, 2022, 06:02:48 pm
I stumbled onto this issue a couple weeks ago with a client that runs our shared library in an AWS Lambda Function environment (using an Amazon Linux 2 base image). Amazon Linux 2 uses a libc version without the pthreads and dl library integration changes, so trying to use our shared library built on the most recent stable Ubuntu release (or Fedora) results in an error.

Amazon is working on a new version of Amazon Linux (2022) with updated glibc support, but it does not seem ready yet and who knows when our client will decide to move over to that base image instead of AL2.

To address the problem, I am currently building a container based on Ubuntu 20.04 that will add the necessary dependencies to build FPC and Lazarus via fpcupdeluxe, and use distrobox to use that as my dedicated Lazarus build environment.

Alan
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on December 02, 2022, 07:25:33 pm
libc without pthreads... yes, I've come across that combination on an x86_64 tablet when investigating FPC with Termux.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on April 29, 2023, 07:04:14 pm
my apologies for resurrecting an old thread, but here seems to be the most complete discussion of the matter... i just experienced the disastrous consequences of pushing out a software release compiled on a recent linux install (mint 21.1) that ended up linked against glibc 2.34. the outcome was a right mess, and i just spent several hours in a panic creating an old mint 19.3 VM to create a working executable that i could substitute.

here is the output i get from objdump -T progname | grep -i glibc piped through diff to show just the differences between 'bad' and 'good' executables:
Code: [Select]
                                  > (GLIBC_2.2.5) dlsym
(GLIBC_2.34) dlerror       | (GLIBC_2.2.5) dlclose
(GLIBC_2.34) dlopen               <
(GLIBC_2.34) dlclose              <
(GLIBC_2.34) __libc_start_main    | (GLIBC_2.2.5) dlerror
(GLIBC_2.34) dlsym                <
                                  > (GLIBC_2.2.5) dladdr
                                  > (GLIBC_2.2.5) dlopen
(GLIBC_2.34) dladdr               | (GLIBC_2.2.5) __libc_start_main

it seems the difference is not insurmountably large - just a few symbols - is there not surely some simple way to pick up the library file:  /lib/x86_64-linux-gnu/libc-2.27.so  and place it where the linker will find and make use of it? a whole VM just to fix 6 small differences seems quite excessive. i have read through the various threads on this and other forums, and it seems to me that there is a great deal of philosophical debate going on (for instance: https://gitlab.com/freepascal.org/fpc/projects/-/issues/3 (https://gitlab.com/freepascal.org/fpc/projects/-/issues/3)), with little pragmatic consideration.

the status quo: sending someone a program file that simply does not run, is a bit of a disaster. i feel we should be able to do better.


help, someone, please?


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on April 29, 2023, 08:52:32 pm
the status quo: sending someone a program file that simply does not run, is a bit of a disaster. i feel we should be able to do better.

Compared with my comments to (and about) the developers about various build problems, I think you're being remarkably restrained :-)

I think your problem cries out for something like a Docker container, or an Appimage. Having seen various compatibility issues relating to Docker I think I'd lean towards the latter, but I don't know how to do it.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on April 29, 2023, 09:00:08 pm
... is there not surely some simple way to pick up the library file:  /lib/x86_64-linux-gnu/libc-2.27.so  and place it where the linker will find and make use of it?
There is not a proficiency present in the compiler / build system that I am aware of.

I would copy the required/wanted file to somewhere else and use the Fl option to point the compiler towards that directory. You could use a define in case you wish to support multiple glibc versions.

You/we (FPC) are not he only one facing this issue. It is easy to find online instructions on how to build an older version of glibc and what do do with it (when it comes to compiling/building).


Quote
the status quo: sending someone a program file that simply does not run, is a bit of a disaster. i feel we should be able to do better.
As said, FPC is not the only compiler having to deal with this issue (more accurate: the dev using the compiler)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: sketch on April 29, 2023, 09:10:12 pm
You can have multiple versions of glibc installed on your server.
Code: [Select]
wget https://ftp.gnu.org/gnu/glibc/glibc-2.2.5.tar.gz
tar -xvzf glibc-2.2.5.tar.gz
cd glibc-2.2.5
mkdir build
cd build
../configure --prefix=~/opt/glibc-2.2.5 #or wherever you prefer
make -j8 #or however many procs you have
make install #add sudo if you don't have write privileges like to /usr/local in prefix

Then in C++ you want to use -Wl,--rpath=~/opt/glibc-2.2.5 and -Wl,--dynamic-linker=~/opt/glibc-2.2.5/ld-linux.so.2.27.  I'm not sure how you set those in FPC.

Or if you have patchelf installed, then you can run that with the path to ld-linux.so.2.27 and the rpath to where your new glibc is installed against the binary you've already created.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on April 29, 2023, 11:43:28 pm
Then in C++ you want to use -Wl,--rpath=~/opt/glibc-2.2.5 and -Wl,--dynamic-linker=~/opt/glibc-2.2.5/ld-linux.so.2.27.  I'm not sure how you set those in FPC.

You can pass paths to the linker with -Xr and the dynamic linker with -FD.

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on April 30, 2023, 02:37:18 pm
i've tried all combinations of -Fl, -Xr and -FD plugged into the Custom Options field in the IDE, but the result when compiling is always much the same:

Code: [Select]
Warning: Only one source file supported, changing source file to compile from "~/pascal/GFXterm 2.1c/libc.so.6" into "project1.lpr"
i've got two copies of the 'good' library file (uplifted from mint 19.3), one named libc.so.6, the other named libc-2.27.so, sitting in my project folder. i've also tried copying these into the lib/x86_64-linux directory of my project. but no luck. it seems that persuading the IDE to allow picking up a library from somewhere other than what it considers to be the correct location is not so easy!

an idea that did occur: could one be tricky and create a 'fake' dynamic library containing just the 6 offending symbols, convincing lazarus that the symbols are not part of the operating system? this library does not need to be functional, just provide the symbols and links that go either nowhere or to empty routines. the fake library would serve purely to 'guide' the compiling/linking process, and would be deleted/removed/renamed once that is finished.

btw: i am far from a linux expert, but i do usually manage to muddle my way through!


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on April 30, 2023, 04:30:15 pm
i've got two copies of the 'good' library file (uplifted from mint 19.3), one named libc.so.6, the other named libc-2.27.so, sitting in my project folder. i've also tried copying these into the lib/x86_64-linux directory of my project. but no luck. it seems that persuading the IDE to allow picking up a library from somewhere other than what it considers to be the correct location is not so easy!

Snippet for you: I'm not sure to what extent this is universal behaviour, but my experience on Linux is that any library symlinks are resolved at build- rather than run-time.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on April 30, 2023, 05:51:22 pm
i've tried all combinations of -Fl, -Xr and -FD plugged into the Custom Options field in the IDE, but the result when compiling is always much the same:

Code: [Select]
Warning: Only one source file supported, changing source file to compile from "~/pascal/GFXterm 2.1c/libc.so.6" into "project1.lpr"
i've got two copies of the 'good' library file (uplifted from mint 19.3), one named libc.so.6, the other named libc-2.27.so, sitting in my project folder. i've also tried copying these into the lib/x86_64-linux directory of my project. but no luck. it seems that persuading the IDE to allow picking up a library from somewhere other than what it considers to be the correct location is not so easy!
That is strange (or I am extremely lucky).

When I use FPC from the commandline and have another version of libc.so located in the directory from which I invoke FPC then FPC automatically/firstly picks up on that libc.so (according to gnu ld linker). I do have another issue but that is my fault as I also need to use/build the correct pthreads lib.

Have you tried to look at what adding the FPC option -k--trace produces for you ?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on April 30, 2023, 07:27:15 pm
i've tried all combinations of -Fl, -Xr and -FD plugged into the Custom Options field in the IDE, but the result when compiling is always much the same:

Code: [Select]
Warning: Only one source file supported, changing source file to compile from "~/pascal/GFXterm 2.1c/libc.so.6" into "project1.lpr"
i've got two copies of the 'good' library file (uplifted from mint 19.3), one named libc.so.6, the other named libc-2.27.so, sitting in my project folder. i've also tried copying these into the lib/x86_64-linux directory of my project. but no luck. it seems that persuading the IDE to allow picking up a library from somewhere other than what it considers to be the correct location is not so easy!

an idea that did occur: could one be tricky and create a 'fake' dynamic library containing just the 6 offending symbols, convincing lazarus that the symbols are not part of the operating system? this library does not need to be functional, just provide the symbols and links that go either nowhere or to empty routines. the fake library would serve purely to 'guide' the compiling/linking process, and would be deleted/removed/renamed once that is finished.

btw: i am far from a linux expert, but i do usually manage to muddle my way through!


cheers,
rob   :-)

Hello.

Maybe not related but, fpc using "external", does not allow "extended" so extension ( libc.so.6 vs libc.so ).
You may try using a symlink libc.so with target libc.so.6.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on April 30, 2023, 09:36:03 pm
IIRC you also needed -Xd to omit built-in paths. But it is all quite some time ago for me that I did it routinely, and the T_* files in the compiler might have changed since.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on April 30, 2023, 09:44:11 pm
Maybe not related but, fpc using "external", does not allow "extended" so extension ( libc.so.6 vs libc.so ).
You may try using a symlink libc.so with target libc.so.6.

Now that's an interesting one. If my understanding that symlinks are resolved early is correct, that means that a symlink such as libc.so in the project directory would be followed at build time, allowing a reference to an "alien" version of libc without jeopardising the stability of the remainder of the system.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on April 30, 2023, 10:10:07 pm
@MarkMLI: That is correct.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on May 01, 2023, 02:13:10 am
I find it hard to believe that its not easier (and safer) to have a VM setup with a older OS such as U20.04 or Bullseye and do your 'release' builds there. I have such a VM, it has nothing except the things I know are needed to build and package. It's also good in that it will tell me if I have become dependent on a library I installed for another reason on my working machine that needs to be added to dependency list. Doing release builds on a dev system is not a great idea IMHO.

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 01, 2023, 11:12:44 am
I find it hard to believe that its not easier (and safer) to have a VM setup

well, i was going to disagree with dbannon, but then tried what Fred vS suggested:

Maybe not related but, fpc using "external", does not allow "extended" so extension ( libc.so.6 vs libc.so ).
You may try using a symlink libc.so with target libc.so.6.

i placed libc.so in the project directory, and things happened... but unfortunately not quite in the way that i had hoped for! the presence of an 'old' libc.so rippled through the entire build of everything else that had built when anything was installed on the machine. so it would seem that the presence of the 'old' libc.so may needs to be strictly limited to just when the final executable is being put together. i can't see any sensible way to achieve this.

Code: [Select]
Compile Project, Mode: Release, Target: project1: Exit code 1, Errors: 1, Hints: 4
Hint: Start of reading config file /etc/fpc.cfg
Hint: End of reading config file /etc/fpc.cfg
unit1.pas(216,7) Hint: Local const "SoftwareKey" is not used
unit1.pas(365,7) Note: Local variable "CPC" not used
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `lstat64@GLIBC_2.33'
linker: /usr/bin/ld: /lib/x86_64-linux-gnu/libmount.so.1: undefined reference to `fstatat@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_trywrlock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_wrlock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlinfo@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_init@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `fcntl64@GLIBC_2.28'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `stat64@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_create@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `close_range@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `lstat@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlclose@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_tryrdlock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_detach@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_setname_np@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_key_delete@GLIBC_2.34'
linker: /usr/bin/ld: /lib/x86_64-linux-gnu/libselinux.so.1: undefined reference to `gettid@GLIBC_2.30'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlsym@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_unlock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_setspecific@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlopen@GLIBC_2.34'
linker: /usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `statx@GLIBC_2.28'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `fstat64@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_init@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_sigmask@GLIBC_2.32'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlerror@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_getspecific@GLIBC_2.34'
linker: /usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `dn_expand@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutex_trylock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_destroy@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_attr_setstacksize@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_join@GLIBC_2.34'
linker: /usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `res_nquery@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_settype@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_rdlock@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `stat@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `fstat@GLIBC_2.33'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_once@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dladdr@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_destroy@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_key_create@GLIBC_2.34'
linker: /usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dladdr1@GLIBC_2.34'
project1.lpr(24,1) Error: Error while linking

That is strange (or I am extremely lucky).
[...]
Have you tried to look at what adding the FPC option -k--trace produces for you ?

i suspect you are extremely lucky! i'm picking that it is dependent on when everything else on your system was built and what versions of various libraries were present at that time.

using the lazarus IDE, where can "-k--trace" be inserted? i have never tried using FPC at the commandline to build one of my projects.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on May 01, 2023, 01:49:22 pm
i suspect you are extremely lucky! i'm picking that it is dependent on when everything else on your system was built and what versions of various libraries were present at that time.
Sorry I thought it was clear from fredvs' comment. I placed the literal named file "libc.so" in my build directory. and end up with your result.

Quote
using the lazarus IDE, where can "-k--trace" be inserted? i have never tried using FPC at the commandline to build one of my projects.
Lazarus has a special linker section for that in your project options.

If you have your project open:
- menu -> project -> project options to show the project options window
- in the (left) tree select the root item Compiler Options
- select the node Compilation and linking
- at the bottom at the right side appears at the bottom a section named linking
- check the box "Pass options to linker...."
- you probably only need to add "--trace" (without quotes) to the edit box

Depending on what version of glibc you have compiled (or are using to build against) the thread functions were removed (or added I can't remember which way it is). Point being, I got the same results and I need to either compile libc another way and/or compile the thread library as well.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on May 01, 2023, 02:01:28 pm
Sorry I thought it was clear from fredvs' comment. I placed the literal named file "libc.so" in my build directory. and end up with your result.

A file or a symlink?

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on May 01, 2023, 02:04:15 pm
A file or a symlink?
Literally a file. But because you asked I tried that with a symlink as well -> works.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: sketch on May 01, 2023, 05:14:43 pm
Code: [Select]
$ ldd --version ldd
ldd (Ubuntu GLIBC 2.35-0ubuntu3.1) 2.35

I built a different version of glibc into /tmp/glibc-2.36
Code: [Select]
$ mkdir build
$ cd build
$ ../configure --prefix=/tmp/glibc-2.36
$ make
$ make install

Code: [Select]
$ cat hello.c
#include <stdio.h>

int main(void) {
  printf("hello\n");
  return 0;
}

Build a new executable.
Code: [Select]
$ g++ -Xlinker -Map=b.map -o xhello -static -L /tmp/glibc-2.36/lib -I /tmp/glibc-2.36/include -Wl,--rpath=/tmp/glibc-2.36/lib -Wl,--dynamic-linker=/tmp/glibc-2.36/lib/ld-linux-x86-64.so.2 hello.c

Code: [Select]
$ more b.map
Archive member included to satisfy reference by file (symbol)

/tmp/glibc-2.36/lib/libc.a(libc-start.o)
                              /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-l
inux-gnu/crt1.o (__libc_start_main)
/tmp/glibc-2.36/lib/libc.a(check_fds.o)
                              /tmp/glibc-2.36/lib/libc.a(libc-start.o) (__libc_c
heck_standard_fds)
/tmp/glibc-2.36/lib/libc.a(libc-tls.o)
...

Code: [Select]
$ cd /tmp
$ mv glibc-2.36 noglibc-2.36
$ ls -ld glibc-2.36
ls: cannot access 'glibc-2.36': No such file or directory
$ ./xhello
hello

You can certainly build a static executable using a different version of glibc that you build yourself. Of course I used C++ in the build of the binary, but it should be translatable to fpc.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on May 01, 2023, 05:49:05 pm
...
I built a different version of glibc into /tmp/glibc-2.36
Code: [Select]
$ mkdir build
$ cd build
$ ../configure --prefix=/tmp/glibc-2.36
$ make
$ make install

Hello Sketch and thanks for your tips.
About compiling a old version of libc.so, do you know how to find/get libc.so without install it in the system?
This because the last time that I did this, with $ make install it erased the installed libc.so and after this the system was not working anymore.

Thanks.

Fre;D
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: sketch on May 01, 2023, 06:15:44 pm
On Ubuntu you can use download packages and then extract the contents.
Code: [Select]
$ sudo apt-get download regina-rexx
It will save the package to your CWD.

Code: [Select]
$ ar x regina-rexx_3.6-2.4_amd64.deb
$ ls
control.tar.xz  data.tar.xz  debian-binary  regina-rexx_3.6-2.4_amd64.deb
$ unxz data.tar.xz
$ tar -xvf data.tar
./
./usr/
./usr/bin/
./usr/bin/regina
./usr/bin/rexx
./usr/bin/rxqueue
./usr/bin/rxstack
...
$ cd usr/bin
$ rexx --version

Regina REXX-Regina_3.6 5.00 31 Dec 2011. All rights reserved.
Regina is distributed under the terms of the GNU Library Public License
and comes with NO WARRANTY. See the file COPYING-LIB for details.

To run a Rexx program:
./rexx [-h?vrt[ir]ap] program [arguments...]
...

I would assume Ubuntu has a public repository where you can also download .deb packages. I've downloaded Red Hat RPM packages before to extract them using rpm2cpio before too at the day job.

Hopefully that is what you're looking for?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on May 01, 2023, 06:38:20 pm
A file or a symlink?
Literally a file. But because you asked I tried that with a symlink as well -> works.

Are you talking about the trick to use -Fl, -Xr, Xd  and -FD and symlink without extended number extension?
And saying it works for you?
If yes, could you give the fpc parameters that you used?

Even better, give in attachment the zipped files of old libc.so.6 and other files needed for linking?
 ;)

Thanks.

Fre;D
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on May 01, 2023, 06:46:30 pm
...
Hopefully that is what you're looking for?

Hum, not really but thanks.
Afaik, if somebody want to install in a custom directory with $ sudo make install , a fake system-root directory must be created and use a parameter to use that fake-root-directory instead of the directory of the system.

But if somebody has already done the job, of course I would prefer to use his zipped directory.  ;)

Fre;D
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 02, 2023, 09:20:49 am
- you probably only need to add "--trace" (without quotes) to the edit box

is this the output you are after? my apologies for it being so long, you'll see i needed to trim it before the forum software would let me post it!

i'm thinking more again about a 'fake' libc.so, no functioning code (or just stubs if needsbe) but the necessary symbols to keep the linker happy. one could then within it have defined the necessary minimum version numbers to match the requirements of your project.

i can see (in a warped way) why the linker enforces the minimum versions - it is saying "i can build your project on this machine, but can not be sure the build will run on an older one. i am also assuming that YOU are going to fully test the code i've just built to make sure that everything works fully on this machine".

what the linker does NOT know, however, is the minimum versions are for the your project it has just built. for instance, it might be imposing dlopen@GLIBC_2.34 based upon data it has gleaned from libc.so, but your project may only be making use of dlopen functionality that has been present since the 2.1.0 version.

hence, while there is some rationale behind what the linker is doing, it is acting on incomplete information and it's strategy is flawed.

btw: in the 'Wonderful World of Windows' - where i lived for many years but finally abandoned around 5 years ago - this problem is handled by every documented library call having a revision history, where history markers may be '2000', 'XP', 'XP SP3', '7', etc. when coding to use any library function, one just checks the level of functionality available at your minimum target level and make sure to not use any later functionality.


cheers,
rob   :-)


Code: [Select]
Hint: (11030) Start of reading config file /etc/fpc.cfg
Hint: (11031) End of reading config file /etc/fpc.cfg
Free Pascal Compiler version 3.2.0 [2020/07/07] for x86_64
Copyright (c) 1993-2020 by Florian Klaempfl and others
(1002) Target OS: Linux for x86-64
(3104) Compiling project1.lpr
(3104) Compiling unit1.pas
(3104) Compiling unit2.pas
[...]
(3104) Compiling unit3.pas
[...]
(3104) Compiling unit4.pas
[...]
(3104) Compiling unit5.pas
[...]
(9022) Compiling resource /home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/project1.or
(9015) Linking /home/user/pascal/GFXterm 2.1c/project1
/usr/lib/x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/si_c.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/abitag.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/project1.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/project1.or
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/system.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/fpintres.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/objpas.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/cthreads.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/interfaces.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/forms.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/unit1.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/linux.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/unixcp.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2disableliboverlay.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2int.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/classes.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/x11/x.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/gtk2/gdk2x.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/gtk2/pango.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazfileutils.o
[...]
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazstringutils.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/dialogs.o
[...]
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lcltype.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/graphtype.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/graphmath.o
[...]
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2msgqueue.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/x11/xrender.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/cairo/cairo.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/gtk2/atk.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazutilsstrconsts.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/fpcadds.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl-objpas/strutils.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/gettext.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazclasses.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazmethodlist.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/laz_avl_tree.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/fgl.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/laztracer.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazutilities.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lresources.o
[...]
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lcltaskdialog.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/uitypes.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/fileutil.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl-objpas/variants.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazconfigstorage.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/dynqueue.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazutf8classes.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl-objpas/varutils.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/avglvltree.o
[...]
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazsysutils.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fpimage.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/intfgraphics.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fpreadbmp.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fptiffcmn.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lclversion.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/icnstypes.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fpimgcmn.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/pngcomn.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/paszlib/zstream.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/paszlib/zbase.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/paszlib/gzio.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/hash/crc.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/paszlib/zdeflate.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/paszlib/inffast.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazversion.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/contnrs.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fpcanvas.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/fpreadgif.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lclrescache.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsreferences.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/clipping.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/pasjpeg/jpeglib.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/pasjpeg/jfdctflt.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/syncobjs.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/tmschema.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/masks.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-process/process.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-process/pipes.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/termio.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/custapp.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/customtimer.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/actnlist.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/helpintfs.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/imglist.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/singleinstance.o
[...]
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-image/ellipses.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsimglist.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsproc.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsfactory.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/propertystorage.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/rttiutils.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsmenus.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazlogger.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/chm/fasthtmlparser.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsforms.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/imagelistcache.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/textstrings.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/extendedstrings.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsstdctrls.o
[...]
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wstoolwin.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/gtk2/gtk2ext.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/extdlgs.o
[...]
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/lclmemmanager.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsprivate.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-base/uriparser.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wscontrols.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lazlinkedlist.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsfactory.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsstdctrls.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wschecklst.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2themes.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/spin.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/grids.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/pairsplitter.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsspin.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/fcl-xml/htmldefs.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/maskedit.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/dynamicarray.o
[...]
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/laz2_xmlutils.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsgrids.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wspairsplitter.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsbuttons.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wscalendar.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wscomctrls.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsdialogs.o
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/cthreads.o: in function `CTHREADS_$$_LOADPTHREADS$$BOOLEAN':
cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0xe): undefined reference to `dlopen'
/usr/bin/ld: cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0x34): undefined reference to `dlsym'
/usr/bin/ld: cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0x4e): undefined reference to `dlsym'
/usr/bin/ld: cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0x68): undefined reference to `dlsym'
/usr/bin/ld: cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0x82): undefined reference to `dlsym'
/usr/bin/ld: cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0x9c): undefined reference to `dlsym'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/cthreads.o:cthreads.pp:(.text.n_cthreads_$$_loadpthreads$$boolean+0xb6): more undefined references to `dlsym' follow
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/cthreads.o: in function `CTHREADS_$$_UNLOADPTHREADS$$BOOLEAN':
cthreads.pp:(.text.n_cthreads_$$_unloadpthreads$$boolean+0xd): undefined reference to `dlclose'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dl.o: in function `DL_$$_UNIXGETMODULEBYADDR$POINTER$POINTER$OPENSTRING':
dl.pp:(.text.n_dl_$$_unixgetmodulebyaddr$pointer$pointer$openstring+0x39): undefined reference to `dladdr'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dynlibs.o: in function `DYNLIBS_$$_SYSLOADLIBRARYA$RAWBYTESTRING$$INT64':
dynlibs.pas:(.text.n_dynlibs_$$_sysloadlibrarya$rawbytestring$$int64+0x17): undefined reference to `dlopen'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dynlibs.o: in function `DYNLIBS_$$_SYSGETPROCEDUREADDRESS$INT64$ANSISTRING$$POINTER':
dynlibs.pas:(.text.n_dynlibs_$$_sysgetprocedureaddress$int64$ansistring$$pointer+0x12): undefined reference to `dlsym'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dynlibs.o: in function `DYNLIBS_$$_SYSUNLOADLIBRARY$INT64$$BOOLEAN':
dynlibs.pas:(.text.n_dynlibs_$$_sysunloadlibrary$int64$$boolean+0x6): undefined reference to `dlclose'
/usr/bin/ld: /usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dynlibs.o: in function `DYNLIBS_$$_SYSGETLOADERRORSTR$$SHORTSTRING':
dynlibs.pas:(.text.n_dynlibs_$$_sysgetloaderrorstr$$shortstring+0xd): undefined reference to `dlerror'
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsextctrls.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsextdlgs.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsforms.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsgrids.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsimglist.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsmenus.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wsspin.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2wspairsplitter.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/unitywsctrls.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2cellrenderer.o
/usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/gtk2/gtk2listviewtreemodel.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/unit2.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/unit3.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/unit4.o
/home/user/pascal/GFXterm 2.1c/lib/x86_64-linux/unit5.o
/usr/share/lazarus/2.0.12/components/lazutils/lib/x86_64-linux/lconvencoding.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/dos.o
/usr/lib/fpc/3.2.0/units/x86_64-linux/rtl/strings.o
/usr/lib/x86_64-linux-gnu//libpthread.a
/usr/lib/x86_64-linux-gnu//libasound.so
/usr/lib/x86_64-linux-gnu//libdl.a
/usr/lib/x86_64-linux-gnu//libgdk-x11-2.0.so
/usr/lib/x86_64-linux-gnu//libX11.so
/usr/lib/x86_64-linux-gnu//libgdk_pixbuf-2.0.so
/usr/lib/x86_64-linux-gnu//libgtk-x11-2.0.so
/usr/lib/x86_64-linux-gnu//libgobject-2.0.so
/usr/lib/x86_64-linux-gnu//libglib-2.0.so
/usr/lib/x86_64-linux-gnu//libgthread-2.0.so
/usr/lib/x86_64-linux-gnu//libgmodule-2.0.so
/usr/lib/x86_64-linux-gnu//libpango-1.0.so
/usr/lib/x86_64-linux-gnu//libcairo.so
/usr/lib/x86_64-linux-gnu//libatk-1.0.so
./libc.so
/usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o
/usr/lib/x86_64-linux-gnu/crtn.o
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `lstat64@GLIBC_2.33'
/usr/bin/ld: /lib/x86_64-linux-gnu/libmount.so.1: undefined reference to `fstatat@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_trywrlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_wrlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlinfo@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_init@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `fcntl64@GLIBC_2.28'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `stat64@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_create@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `close_range@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `lstat@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlclose@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_tryrdlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_detach@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_setname_np@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_key_delete@GLIBC_2.34'
/usr/bin/ld: /lib/x86_64-linux-gnu/libselinux.so.1: undefined reference to `gettid@GLIBC_2.30'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlsym@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_unlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_setspecific@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlopen@GLIBC_2.34'
/usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `statx@GLIBC_2.28'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `fstat64@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_init@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_sigmask@GLIBC_2.32'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dlerror@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_getspecific@GLIBC_2.34'
/usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `dn_expand@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutex_trylock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_destroy@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_attr_setstacksize@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_join@GLIBC_2.34'
/usr/bin/ld: /lib/x86_64-linux-gnu/libgio-2.0.so.0: undefined reference to `res_nquery@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_mutexattr_settype@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_rdlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `stat@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `fstat@GLIBC_2.33'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `pthread_once@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dladdr@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_rwlock_destroy@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libglib-2.0.so: undefined reference to `pthread_key_create@GLIBC_2.34'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu//libasound.so: undefined reference to `dladdr1@GLIBC_2.34'
/home/user/pascal/GFXterm 2.1c/project1.lpr(24,1) Error: (9013) Error while linking
/home/user/pascal/GFXterm 2.1c/project1.lpr(24,1) Fatal: (10026) There were 1 errors compiling module, stopping
Fatal: (1018) Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 02, 2023, 11:11:08 am
- you probably only need to add "--trace" (without quotes) to the edit box

or are you after the file link.res?


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on May 02, 2023, 12:46:01 pm
Are you talking about the trick to use -Fl, -Xr, Xd  and -FD and symlink without extended number extension?
And saying it works for you?
I am saying that I am investigating if the normal route can be made shorter (meaning that I can compile the required libraries myself instead of the need to copy them over from an older system) and see if it can be done in a bit more civil manner (other then sysrooting etc)).

Quote
Even better, give in attachment the zipped files of old libc.so.6 and other files needed for linking?
 ;)
I have no problem zipping up the libraries from an older (debian) system and make them available. But why rely on someone else ? I do not even trust myself ;D

In the (FPC) compiler's point of view it is nothing more than cross-compiling to another platform. See for instance https://wiki.freepascal.org/Cross_Compile_to_RasPi_from_Linux (note the instructions to archive files from a raspberry pi and copy them over to your host).
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on May 02, 2023, 12:56:02 pm
is this the output you are after? my apologies for it being so long, you'll see i needed to trim it before the forum software would let me post it!
Thank you for having posted your output.

Yes, that is the /first/ step of output that helps to determine what the linker does (which files it pick up on from what directory). I am missing the part(s) where it picks up on the correct files though (at first glance it looks to me as a 'normal' compilation)

Quote
i'm thinking more again about a 'fake' libc.so, no functioning code (or just stubs if needsbe) but the necessary symbols to keep the linker happy. one could then within it have defined the necessary minimum version numbers to match the requirements of your project.
Yes, also a possibility according to some online posts but do note that other report that this also could give issues (It goes out of scope for me to repeat those issues here as most go beyond my technical understanding)

Quote
what the linker does NOT know, however, is the minimum versions are for the your project it has just built. for instance, it might be imposing dlopen@GLIBC_2.34 based upon data it has gleaned from libc.so, but your project may only be making use of dlopen functionality that has been present since the 2.1.0 version.
Yes, that is how I understand things to be/work as well.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on May 02, 2023, 12:58:58 pm
or are you after the file link.res?
That is indeed another step in the process to determine what the linker actually does.

Not entirely what I was looking right now (though it does help) for as the first step (trace) already seem to indicate it picks up on things in a wrong manner. Do note that I myself am not even looking at Lazarus yet but just pure FPC (in order to run we first need to walk  ;D )

edit: I had a closer look. Yes, it seems to pickup on the correct libc. That raises the following question: did you have the units recompiled using the "other" libc ? Note that I am currently facing the exact same issue and am trying to wrap my head around the removal of phthread from libc (in theory it should not matter but afaik you would need to compile/link against libpthreads as well).

Note that currently I am experimenting and gain/obtain the information as I go along (slowly). So, please be careful  :)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 02, 2023, 02:08:32 pm
[...]
edit: I had a closer look. Yes, it seems to pickup on the correct libc. That raises the following question: did you have the units recompiled using the "other" libc ? Note that I am currently facing the exact same issue and am trying to wrap my head around the removal of phthread from libc (in theory it should not matter but afaik you would need to compile/link against libpthreads as well).

i deleted the lib//x86_64-linux folder from my project folder before building. i assumed this would force a recompile of all the project's units - in my case units 1-5. or do you mean recompile the LCL and all the other units that sit in the lazarus directories? if so, how do i do this? i tried doing a "Run" -> "Clean up and Build..." but it fails to delete most of the files - see attached screenshot.

So, please be careful  :)

oh yes, i am being careful! i've had my share of disasters in the past when "rushing in where...".


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on May 02, 2023, 02:18:35 pm
@robert rozee
I don't believe that Lazarus automatically recompiles the FPC units when you rebuild the IDE. My first idea/hunch is to try recompile at least FPC unit cthreads.

I have no idea why you seem unable to delete the file(s) as shown. Note that I do not have fpc/lazarus installed using the OS' package manager or otherwise. I have mine installed completely stand-alone not depending on any system paths (except for those that I have manually added to the compiler options).

Also note that Lazarus version 2.0.12 is /very/ old (read officially unsupported)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 02, 2023, 03:20:06 pm
I have no idea why you seem unable to delete the file(s) as shown
[...]
Also note that Lazarus version 2.0.12 is /very/ old (read officially unsupported)

have just updated lazarus to 2.2.6. no obvious changes to the earlier behavior observed when bringing in the old libc.so to the project directory.

the files are all created by the installer from the .deb package, which runs as root. hence all the files are 'owned' by root. now i do remember i once accidentally ran the IDE as root, and it created a right mess, so am disinclined to go down that path again in a hurry! will look at creating a VM tomorrow to experiment on.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 02, 2023, 03:31:02 pm
just realized, i don't need to build another VM - i already have a brand new mint 19.3 VM with 2.2.6 installed. tried doing a "Run" -> "Clean up and Build..." on that and it behaved just the same, refused to delete the files not in my project directory.

is this perhaps a bug/oversight in lazarus - when trying to delete files in places like /usr/share lazarus should surely be wrapping it in a sudo? not a problem that crops up under windows i'd imagine, so maybe no one has tried/tested it under linux.

are you operating as root permanently on your machine? there are some distros that do this.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on May 02, 2023, 03:44:41 pm
Are you talking about the trick to use -Fl, -Xr, Xd  and -FD and symlink without extended number extension?
And saying it works for you?
I am saying that I am investigating if the normal route can be made shorter (meaning that I can compile the required libraries myself instead of the need to copy them over from an older system) and see if it can be done in a bit more civil manner (other then sysrooting etc)).

I did fight last night with a older libc.so in the same directory of the project but I get same errors as Robert.
And playing with  -Fl, -Xr, Xd  and -FD did not help.

One of the problem is, for example, libX11.so of the system is not happy with the older libc.so ( it want methods of last libc.so installed in system).
So it seems that all the system must be installed using that old libc.so.

Of course it would be better to have the possibility to use a different libc.so to link the program but, at the end, I fear that using a virtual box with a older distro will be easier.

That said, if you find the way to do it with a "fake libc.so system", I buy it.

Fre;D
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 02, 2023, 04:13:30 pm
there is also another problem to consider - lazarus 2.2.6 won't run on all older linux distros    >:(

i had a go with a mint 7 VM, and none of the three .deb files would even open. while with mint 16 there were dependencies that couldn't be met as 16's update manager wouldn't work. so the 'oldest' distro i can run lazarus on (mint 19.3, presumably 19.0 will also work) is relatively new.

given that lazarus is built with lazarus (well, fpc), i can see us "painting ourselves into a corner". today's 2.2.6 will install and run on systems without libc 2.34, but what happens with the next release (or the release after that) when installation itself requires 2.34? at that point it will no longer be possible to do a compile on any older system. in a sense, it is a form of forced obsolescence.

so much for the being able to 'compile once, run anywhere' that windows gave us!


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on May 02, 2023, 06:30:15 pm
so much for the being able to 'compile once, run anywhere' that windows gave us!
I'm currently a bit busy to be able to write a elaborated response but as a quick note: you can always compile Free Pascal and Lazarus manually from source (it isn't that difficult to do) or use FPCDeluxe (https://wiki.freepascal.org/fpcupdeluxe) to do it for you.

The experience you described is exactly why I do not use the systems package manager (amongst other things such as strange divide of packages on some distributions).
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on May 02, 2023, 10:22:06 pm
I'm currently a bit busy to be able to write a elaborated response but as a quick note: you can always compile Free Pascal and Lazarus manually from source (it isn't that difficult to do) or use FPCDeluxe (https://wiki.freepascal.org/fpcupdeluxe) to do it for you.

But the interplay of compiler and source versions can be particularly obscure, and well beyond the abilities of a less-experienced practitioner to work out.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on May 02, 2023, 11:55:32 pm
there is also another problem to consider - lazarus 2.2.6 won't run on all older linux distros    >:(
...
so much for the being able to 'compile once, run anywhere' that windows gave us!

Hum, if I may and afaik, 'compile once, run anywhere' is the slogan of fpc.

Re-hum, no it seems to be the slogan of Lazarus not fpc (or maybe both?), sorry.

Lazarus is dependent of the widgetset that he uses and indeed, a new Lazarus version that needs last widgetset version could not be compatible with older distros.

Here, the dependencies needed at linking for a Lazarus simple empty form ( using the -sh parameter ):
Code: Bash  [Select][+][-]
  1. INPUT(
  2. -lpthread
  3. -ldl
  4. -lgdk-x11-2.0
  5. -lgtk-x11-2.0
  6. -lX11
  7. -lgdk_pixbuf-2.0
  8. -lgobject-2.0
  9. -lglib-2.0
  10. -lgthread-2.0
  11. -lgmodule-2.0
  12. -lpango-1.0
  13. -lcairo
  14. -latk-1.0
  15. )
  16. GROUP(
  17. -lc
  18. )

And, if I may once again, I have installed last MSEgui + MSEide + fpc on old distros ( + 10 years ) and all is working out-of-the-box and the compiled applications too.
Note too that those MSEgui applications compiled on (very) old distros are running perfectly on last Linux distros.

Here, the dependencies needed at linking for a MSEgui  multi not-empty forms ( using the -sh parameter ):
Code: Bash  [Select][+][-]
  1. )
  2. INPUT(
  3. -lpthread
  4. -ldl
  5. -lX11
  6. )
  7. GROUP(
  8. -lc
  9. )

Ok, ok, I am boring, I leave  :P

Fre;D
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on May 03, 2023, 01:32:53 am
.....
is this perhaps a bug/oversight in lazarus - when trying to delete files in places like /usr/share lazarus should surely be wrapping it in a sudo? not a problem that crops up under windows i'd imagine, so maybe no one has tried/tested it under linux.

No, no , no (I almost did a Thaddy there). Lazarus should never be able to delete files in /usr/.   When Lazarus finds itself in a situation where it's own source files (and obj etc) are in root space, it moves its operations down to user space, in the PCP. So, asking for a sudo never need happen, the situation would never, ever arise ....

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 04, 2023, 11:11:44 am
it would certainly seem to be much simpler to have lazarus, from the get-go, install and run in /home/... instead of /usr. amongst other things, it would get around the complexity created when adding new components to the IDE's component bar. but that is another topic!

there are hints of a solution here:
https://stackoverflow.com/questions/21018216/rewrite-shared-library-undef-symbol-version-of-compiled-object/21059674#21059674 (https://stackoverflow.com/questions/21018216/rewrite-shared-library-undef-symbol-version-of-compiled-object/21059674#21059674):
Quote
Removing version info post-link is infeasible -- these strings are entered into hash tables, and rebuilding these hash tables is too complicated a thing to do with objcopy.

What you want to do is create a stub libssl.so.10 with DT_SONAME set to libssl.so.10, which defines all the symbols you need from it, but without any version info. For example, this would do if you only needed the SSL_new symbol:
Code: [Select]
echo "void SSL_new() { }" > t.c &&
 gcc -fPIC -shared -o libssl.so -Wl,--soname='libssl.so.10' t.c

Now link your program against this stub library, and it will not require any versioned symbols.

The runtime linker will then satisfy this undefined unversioned SSL_new with SSL_new@libssl.so.10 on CentOS, and with SSL_new@Base on CloudLinux.


cheers,
rob   :-)


addendum: tried with a file called test.c containing the following:
Code: C  [Select][+][-]
  1. // 2.34
  2.  
  3. void __libc_start_main() { }
  4. void dlsym() { }
  5. void dladdr() { }
  6. void dlclose() { }
  7. void dlerror() { }
  8. void dlopen() { }
  9.  
  10. // 2.2.5
  11.  
  12. void sysconf() { }
  13. void sched_yield() { }
  14.  
  15. void wcscoll() { }
  16. void strcoll() { }
  17.  
  18. void iconv() { }
  19. void iconv_open() { }
  20. void iconv_close() { }
  21.  
  22. void setenv() { }
  23. void setlocale() { }
  24. void nl_langinfo() { }
  25.  
  26. void mbrlen() { }
  27. void mbrtowc() { }
  28. void wcrtomb() { }
  29.  
  30. void __errno_location() { }
  31. void __cxa_finalize() { }
  32.  
  33.  
  34. unsigned int towlower(unsigned int i) { }
  35. unsigned int towupper(unsigned int i) { }
(above code updated 21 may 2023)

and compiled with the below gcc commandline to produce a libc.so:
Code: [Select]
gcc -fPIC -shared -o libc.so -Wl,--soname='libc.so.6' test.c

did something, but not what we want!
21 may 2023: produces 486 warnings but no explicit errors, but still fails:
Code: [Select]
Compile Project, Mode: Release, Target: project1: Exit code 1, Errors: 1
project1.lpr(24,1) Error: Error while linking

full list of warnings, etc attached below

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MarkMLl on May 04, 2023, 12:53:31 pm
Quote
What you want to do is create a stub libssl.so.10 with DT_SONAME set to libssl.so.10, which defines all the symbols you need from it,

When "stub" is used in that context, does it actually mean a linker script? Debian tried that for libusb-0.1, and the result was that anything that tried to load it dynamically (i.e. under explicit program control) also had to be prepared to parse that script in order to determine the name of the actual compatibility library.

MarkMLl
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on May 11, 2023, 03:36:20 am
As it seems to have quietened down a touch here, below is an updated version of the small table I posted on page one -

The issue as we know is that, on Linux system, binaries compiled on a system with glib6-2.34 or later will not work on systems using an earlier glibc6. These Ubuntu and Debian distros use the following glibc6 -

Distros that can make binaries that will run irrespective of the version of libc6 -
Distros that cannot make a binary to run on systems with 'earlier' libc6 -

Not withstanding the efforts of people in previous posts of this thread, the most practical solution still seems to be to have an old install of, perhaps U20.04, perhaps in a VM, to build release versions of your app.

(Sorry, I am not tracking the RPM world, RedHat, as a distro has quite long support ...)

Davo 

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 11, 2023, 07:29:43 am
i've had close to zero success finding a good solution. one nugget of information though, from https://sourceware.org/glibc/wiki/Glibc%20Timeline (https://sourceware.org/glibc/wiki/Glibc%20Timeline):
Date          Release
2021-08-02    GLIBC 2.34
...
2012-03-21    GLIBC 2.15
...
2002-01-20    GLIBC 2.2.5

the above suggests to me that the recent version requirements (2.34 or later) are 'breaking' something that had been not broken for a couple of decades.

has anyone looked into what changes to the linker might be a solution? (1) a switch that disables embedding ANY minimum version requirement for instance? or (2) a switch that allows setting an explicit version requirement? ie, so you could explicitly set 2.2.5?

at the moment it remains that neither the linker nor the library (libc.so.6) has ANY information about what the code it is linking actually requires, and so is enforcing an arbitrary rule. the one source of knowledge - the programmer - is excluded from the decision making process.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on May 11, 2023, 08:02:32 am
Robert, please look back on page one of this thread. As usual, PascalDragon's posts are authoritative.

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 11, 2023, 10:32:28 am
Robert, please look back on page one of this thread. As usual, PascalDragon's posts are authoritative.

Davo

you are referring to the link in reply #6:
https://sourceware.org/git/?p=glibc.git;a=commit;h=035c012e32c11e84d64905efaf55e74f704d3668 (https://sourceware.org/git/?p=glibc.git;a=commit;h=035c012e32c11e84d64905efaf55e74f704d3668)
"A new symbol version __libc_start_main@@GLIBC_2.34 is introduced because new binaries running on an old libc would not run their ELF constructors, leading to difficult-to-debug issues."?

and yet a way of defeating the introduction of this new symbol version exists, insofar as simply compiling on an 'old' VM that uses the 2002 era glibc 2.2.5. does this workaround not prove that the mechanism introduced is ineffective? i would have thought that a better approach would be for any 'new binary' to check the version of libc served up to it, and perform the 'run their ELF constructors' step dependant upon the version of libc found at runtime?

now from the point of view of the helpdesk staff, the solution is even simpler: tell the customer to "just download the WindowsTM version of our application. you'll find there was a free WindowsTM CD that shipped with your computer, pop it in the slot and follow the simple onscreen instructions..."


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on May 11, 2023, 12:51:12 pm
...
Distros that cannot make a binary to run on systems with 'earlier' libc6 -
  • U21.04  - 2.33
  • U21.10  - 2.34  (Impish)
  • U22.04 -  2.35  (Jammy)
  • Linux Mint 21.1
  • Debian Bookworm - 2.36 (release in a few months)

...

Note too that those distros accept only some libraries compiled on those last distros.

For example, the library libsndfile.so from earlier distros cannot be used in the last distros mentioned ( and libsndfile.so from last distros does not work on previous distros), so no solution of backward compatibility here.

Fre;D
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on May 11, 2023, 02:12:10 pm
.......
Note too that those distros accept only some libraries compiled on those last distros.

For example, the library libsndfile.so from earlier distros cannot be used in the last distros mentioned ( and libsndfile.so from last distros does not work on previous distros), so no solution of backward compatibility here.

Hum, I am not sure I like what the core-dev of Linux have done recently.

Fre;D

Fred, I don't think anyone ever suggested that every  Library is forward compatible.  That would be quite impossible because the new system would not find the new functions in old library that it expects, functions that had not been thought of when the older version of the library was made.

A library is expected to be backwards compatible, that is, offer the same services as a earlier version did. Generally, a binary application is expected to be forward compatible, it should run on future systems (because the libraries on that future system are backwards compatible).

In this situation, we asking for our binary application to be backward compatible and its NOT. Its an absolute pain in what you sit on and I desperately wish it had not be allowed to happen but it did happen. And its entirely reasonable that it might happen again in the future.

Robert - https://forum.lazarus.freepascal.org/index.php/topic,58888.msg442518.html#msg442518 but you are more than welcome to dig your Windows CD out of the bottom drawer. I wonder what version of Windows it is ?

Davo

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on May 11, 2023, 02:38:30 pm
Fred, I don't think anyone ever suggested that every  Library is forward compatible.  That would be quite impossible because the new system would not find the new functions in old library that it expects, functions that had not been thought of when the older version of the library was made.

A library is expected to be backwards compatible, that is, offer the same services as a earlier version did. Generally, a binary application is expected to be forward compatible, it should run on future systems (because the libraries on that future system are backwards compatible).

In this situation, we asking for our binary application to be backward compatible and its NOT. Its an absolute pain in what you sit on and I desperately wish it had not be allowed to happen but it did happen. And its entirely reasonable that it might happen again in the future.

Of course I dont suggest that a library should be forward compatible.
But for more than 10 years now, libsndfile.so was backward compatible, a older libsndfile.so can be used in newer distros.

And it is the first time, with those last distros that you you mentioned, that is not the case anymore, libsnfile.so must be compiled on the last distro, otherwise it fails to load.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: ASBzone on May 11, 2023, 03:11:50 pm
But for more than 10 years now, libsndfile.so was backward compatible, a older libsndfile.so can be used in newer distros.

But that's not the definition of backwards compatibility.  That's the definition of forwards compatibility.

As long as the new DLL in the new OS still runs programs that were compiled previously, which reference the old DLL, and they still work when you run that old binary on the new OS, then you have backwards compatibility.

That's not what appears to be in place here.  If the app is compiled with the new version is cannot be run, after the fact, on the old version of the OS.   That's not a backwards compatibility issue.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on May 11, 2023, 03:23:01 pm
But for more than 10 years now, libsndfile.so was backward compatible, a older libsndfile.so can be used in newer distros.

But that's not the definition of backwards compatibility.  That's the definition of forwards compatibility.

As long as the new DLL in the new OS still runs programs that were compiled previously, which reference the old DLL, and they still work when you run that old binary on the new OS, then you have backwards compatibility.

That's not what appears to be in place here.  If the app is compiled with the new version is cannot be run, after the fact, on the old version of the OS.   That's not a backwards compatibility issue.

Ha, ok, clear now, thanks.

What I wanted to note ( how to call this ? ) is that before those last distros mentioned,  programs that dynamically loaded libraries with "loadlibrary()" could load older libraries on new distros.
It is not the case for some libraries with those last distros mentioned.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 11, 2023, 03:34:04 pm
Robert - https://forum.lazarus.freepascal.org/index.php/topic,58888.msg442518.html#msg442518 but you are more than welcome to dig your Windows CD out of the bottom drawer. I wonder what version of Windows it is ?

The issue is that newer libcs have a versioned symbol and according to the ELF spec when a symbol that has a version attached is used then this needs to be referenced as such in the ELF binary so that the dynamic linker can then resolve this using the correct version of the symbol, this implicitly also means that if you try to run a binary that uses such a versioned symbol on a system where the corresponding library does not have this symbol with the suitable version (or none at all) then the binary simply won't load. It's as if you'd use a symbol that doesn't exist at all.

Davo: i don't see what you are getting at. PascalDragon is just stating the mechanism used, and on that point we all more-or-less seem to agree. we already know how to 'defeat' it, by building our binaries using an 'old' distro. however, this solution has a limited lifespan if you like, as at some point there will come along a lazarus/FPC that will no longer run on our 'old' distro. at that future time the libc authors can not be 'held accountable', because we are trying to use such an old distro as part of our build process - they will have plausible deniability.

i also understand why this is likely being done, it is an attempt to shed some of the load of maintaining backward compatibility. if the libc authors came out and said this openly, then that wouldn't be so bad. if the authors said " libc.so.6 is old and outdated, we are going to abandon it completely and only work on a new, better libc.so.7 " then i would applaud their bold decision. but instead we see what is essentially a flaw quietly introduced that will lead to an eventual obsolescence/failure that can be blamed (if blaming is needed) on the end user.

without binary application compatibility, linux on the desktop will die. or everything will be written in python.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on May 11, 2023, 03:47:43 pm
But for more than 10 years now, libsndfile.so was backward compatible, a older libsndfile.so can be used in newer distros.

But that's not the definition of backwards compatibility.  That's the definition of forwards compatibility.

As long as the new DLL in the new OS still runs programs that were compiled previously, which reference the old DLL, and they still work when you run that old binary on the new OS, then you have backwards compatibility.

That's not what appears to be in place here.  If the app is compiled with the new version is cannot be run, after the fact, on the old version of the OS.   That's not a backwards compatibility issue.

Ha, ok, clear now, thanks.

What I wanted to note ( how to call this ? ) is that before those last distros mentioned,  programs that dynamically loaded libraries with "loadlibrary()" could load older libraries on new distros.
It is not the case for some libraries with those last distros mentioned.

Ooops, sorry, my fault, the guilty is in libsndfile.so.
So, once again, sorry for the noise, old libraries (apart for some with bug or bad design) can be loaded on those distros mentioned.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: ASBzone on May 11, 2023, 03:57:19 pm
without binary application compatibility, linux on the desktop will die. or everything will be written in python.

Binary application compatibility exists.  Just not in the direction you want, in this case.

It's also interesting that you bring up the example of Python, which is still dealing with the mess of v2 and v3, years later.

Nonetheless, there continue to be different views on the ramifications of what was done, and there are others who feel about the matter similarly as you do:  https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread# (https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread#)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on May 11, 2023, 11:15:05 pm
without binary application compatibility, linux on the desktop will die. or everything will be written in python.

Linux systems are more geared towards open source and compiling applications on the systems where you need them (this includes package managers as there the software is compiled for the current state of the packages as well) thus binary compatiblity to the extend that you expect is usually less of an issue.

Then again you don't necessarily expect to run an application that was programmed for Windows 10 on Windows 7 or even Windows XP. It might work if the author handled it correctly, but it's in no way guaranteed. This is the same situation here: an application compiled for a newer distro doesn't necessarily work on an older one.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on May 12, 2023, 01:29:31 am
libsndfile.so
...
What I wanted to note ( how to call this ? ) is that before those last distros mentioned,  programs that dynamically loaded libraries with "loadlibrary()" could load older libraries on new distros.
It is not the case for some libraries with those last distros mentioned.
But Fred, why not just use the newer version of the library, as the distro builders intend ?  You use Debian, in Bullseye its 1.0.31-2 and in the forthcoming Bookworm, its 1.2.0-1. Its there and its the one that Debian will have subjected to extensive testing.

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on May 12, 2023, 02:11:44 am
........
i also understand why this is likely being done, it is an attempt to shed some of the load of maintaining backward compatibility. ....
Yes, to some degree that is the case. It must, over time, happen. What is surprising really is not that there is an non-backward compatibility issue right now, when you think about it, we should be surprised its worked at all over the last few years. No one has ever set that backward compatibility requirement in an application as a requirement or a guarantee or even a performance measure. We were, for a few years, lucky !


without binary application compatibility, linux on the desktop will die. or everything will be written in python.
Sorry Robert, but that is, frankly, nonsense. * The vast majority of linux application code people use comes from the distribution's repo. Its built from source provided by developers but, importantly, its built using the forerunner of that distribution release. There is no forward or backward comparability issues.

Where its an issue is where developers distribute packages of their application. Again, if you are to follow eg Debian's rules, you would build a specific package, in the right environment, for each and every distribution you target. Few people do that because we have all discovered, through testing, we can make general purpose packages.

For example, my app, tomboy-ng, I submit source code to Debian, they use it to build specific Bullseye and Bookworm packages on, respectively, Bullseye and Bookworm. I also make packages (on github) for people who want the most current release, as generic deb packages (and rpms). I build and package them on an Ubuntu 20.04 machine and I know, because of testing, they will run on even an U18.04 or Buster through to U23.04 and Bookworm. I also release a PPA version, again, built on a U20.04 Launchpad machine. Launchpad allows me to either rebuild for later Ubuntu releases or to 'copy' the binary. I know, from testing, that 'copy' works fine, U20.04 through to U23.04.

(*) sorry if I have offended with use of word 'nonsense' but it does annoy me when people say "unless {insert mildly annoying issue} is fixed, the world will end". The fact is, its entirely manageable. Annoying but manageable !
/quote]

Davo

Ref
https://github.com/tomboy-notes/tomboy-ng/releases/tag/v0.36c
https://packages.debian.org/search?searchon=sourcenames&keywords=tomboy-ng
https://launchpad.net/~d-bannon/+archive/ubuntu/ppa-tomboy-ng
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on May 12, 2023, 12:51:10 pm
libsndfile.so
...
What I wanted to note ( how to call this ? ) is that before those last distros mentioned,  programs that dynamically loaded libraries with "loadlibrary()" could load older libraries on new distros.
It is not the case for some libraries with those last distros mentioned.
But Fred, why not just use the newer version of the library, as the distro builders intend ?  You use Debian, in Bullseye its 1.0.31-2 and in the forthcoming Bookworm, its 1.2.0-1. Its there and its the one that Debian will have subjected to extensive testing.

Davo

Hello Davo.

I will try to explain the problem.

If you take the last version of distro XUbuntu 23.04, here are the dependencies of libsndfile.so:

Code: Bash  [Select][+][-]
  1. ~> ldd /usr/lib/x86_64-linux-gnu/libsndfile.so
  2.  
  3.         linux-vdso.so.1 (0x00007fffa39f9000)
  4.         libFLAC.so.12 => /lib/x86_64-linux-gnu/libFLAC.so.12 (0x00007f6c0dbe1000)
  5.         libvorbis.so.0 => /lib/x86_64-linux-gnu/libvorbis.so.0 (0x00007f6c0dbb4000)
  6.         libvorbisenc.so.2 => /lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007f6c0db09000)
  7.         libopus.so.0 => /lib/x86_64-linux-gnu/libopus.so.0 (0x00007f6c0daae000)
  8.         libogg.so.0 => /lib/x86_64-linux-gnu/libogg.so.0 (0x00007f6c0daa4000)
  9.         libmpg123.so.0 => /lib/x86_64-linux-gnu/libmpg123.so.0 (0x00007f6c0da46000)
  10.         libmp3lame.so.0 => /lib/x86_64-linux-gnu/libmp3lame.so.0 (0x00007f6c0d9d0000)
  11.         libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6c0d8e7000)
  12.         libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6c0d600000)
  13.         /lib64/ld-linux-x86-64.so.2 (0x00007f6c0dcec000)
  14.  

There are 2 problems with the dependencies:
 1) libc.so.6 = same problem as with fpc link: it was linked with last version of libc.so.6 and then will not work on previous distros.
 2) libFLAC.so.12 = this is a new flac version, previous distros used libflac.so.8 ( strict version number needed ).

So, not compatible with my religion "out-of-the-box", if I want give in the release a unique libsndfile.so for new and old distros.

If I use a old version of libsndfile.so compiled with old libc.so.6, we know that libc.so.6 is backward compatible, so it is ok.
But it is not the case for libflac.so.8 that is strict and does not exist in XUbuntu 23.04 ( only exist libflac.so.12 ).
Of course you may create a symlink  libflac.so.8 -> libflac.so.12 but it is bricolage and not out-of-the-box.

So, my solution is to recompile libsndfile.so on a older distro ( for the libc.so.6 problems ) and build statically the deps inside the library.
Fortunately there is a great project that gives the script to do this (wow, it works out-of-the-box):
https://github.com/bastibe/libsndfile-binaries/blob/master/linux_build.sh

Of course that new libsndfile.so is bigger ( 2.5 megas vs 800k ) but no more possible problems of dependencies, all is in the library:

Code: Bash  [Select][+][-]
  1. ~> ldd /home/fred/StrumPract_linux64/lib/Linux/64bit/LibSndFile-64.so
  2.         linux-vdso.so.1 (0x00007ffcf01d0000)
  3.         libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0ff5717000)
  4.         libmvec.so.1 => /lib/x86_64-linux-gnu/libmvec.so.1 (0x00007f0ff561d000)
  5.         libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0ff5400000)
  6.         /lib64/ld-linux-x86-64.so.2 (0x00007f0ff5adb000)
  7.  


So, for the release of StrumPract, the user has 2 choices:

-1) Or use the library installed on system:
     
Code: Pascal  [Select][+][-]
  1.  DynLibs.LoadLibrary('libsndfile.so.1');
     In that case LoadLibrary() will search in all the library-directories defined by the system.

-2) Or use the libraries given in release StrumPract/lib     
     
Code: Pascal  [Select][+][-]
  1.  DynLibs.LoadLibrary('/directory_of_release_lib/custom_libsndfile.so');
     In that case LoadLibrary() will try to load only the path of library defined).

At first loading, if library of system did not load, it will try to load the library from release.
And in setup, user may decide what library use for loading.

Fre;D
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 12, 2023, 12:54:31 pm
Sorry Robert, but that is, frankly, nonsense. * The vast majority of linux application code people use comes from the distribution's repo. Its built from source provided by developers but, importantly, its built using the forerunner of that distribution release. There is no forward or backward comparability issues.

(*) sorry if I have offended with use of word 'nonsense' but it does annoy me when people say "unless {insert mildly annoying issue} is fixed, the world will end". The fact is, its entirely manageable. Annoying but manageable !

no offense taken... and you are quite right - i was over-reacting in my comment   :)   i just find it so frustrating that such a 'visually small' change (even if made for good reasons) can prove so difficult (for me) to work around. i do realize that what i call a 'visually small' change is in fact just the very tip of a very large series of updates and improvements under the hood of libc.so.6 that are probably long overdue.

the sorts of applications i write using lazarus/FPC are generally of interest to a quite limited audience, with maybe just a few hundred users, and usually evolve based upon user feedback. as such they are not the sort of things that would fit in with a distribution's repo, far more suitable for github or similar. and the users are not at a level where they can install lazarus and compile something themselves, while most would balk at the scale of something like a docker container, appimage, flatpak, etc.

this leaves limited options open - and the further i dig, the less confidence i have that building binaries on an old distro is a good long-term solution. i get the feeling that window is slowly closing.


I wonder what version of Windows it is ?

for generating win32 applications i use an XP VM.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on May 14, 2023, 04:42:05 am
......
this leaves limited options open - and the further i dig, the less confidence i have that building binaries on an old distro is a good long-term solution. i get the feeling that window is slowly closing.
....

for generating win32 applications i use an XP VM.

I would think your Linux solution would be exactly the same as your Windows solution. Ubuntu 20.04 is supported for several years yet, run it in a VM as a dedicated build environment, always a good idea IMHO.

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on May 14, 2023, 04:58:40 am
Fred, sorry, I really don't quite understand your problem, currently in an aeroplane and difficult to concentrate. But I am guessing its similar to what this thread is about. When we find we can build binaries that run on a wide range of systems, we should feel lucky !

Sigh ...

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on May 20, 2023, 08:04:16 pm
a little more back story, gleaned from:
https://codebrowser.dev/glibc/glibc/csu/libc-start.c.html (https://codebrowser.dev/glibc/glibc/csu/libc-start.c.html)

lines 392-397:
Code: C  [Select][+][-]
  1. /* Starting with glibc 2.34, the init parameter is always NULL.  Older
  2.    libcs are not prepared to handle that.  The macro
  3.    DEFINE_LIBC_START_MAIN_VERSION creates GLIBC_2.34 alias, so that
  4.    newly linked binaries reflect that dependency.  The macros below
  5.    expect that the exported function is called
  6.    __libc_start_main_impl.  */

line 223-228:
Code: C  [Select][+][-]
  1. /* Note: The init and fini parameters are no longer used.  fini is
  2.    completely unused, init is still called if not NULL, but the
  3.    current startup code always passes NULL.  (In the future, it would
  4.    be possible to use fini to pass a version code if init is NULL, to
  5.    indicate the link-time glibc without introducing a hard
  6.    incompatibility for new programs with older glibc versions.)

and from an article someone (i believe) previously linked:
https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread (https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread)
Quote
Jeremy Andrews 9 months ago
It's worth noting that this change breaks some older applications that were compiled against glibc earlier than 2.34. It's very hit and miss, but I have encountered older applications that don't work at all on 2.34 and work fine on 2.33, and any kind of attempt to debug shows that things are getting gummed up in futex-internal or that pthread_mutex_lock isn't working. Mostly it seems to happen where stack protection is involved.

these three excerpts tell us:
1. the parameters to _libc_start_main (or more correctly LIBC_START_MAIN()) include init and fini. these are entry points to the user (application) program (not 100% sure about fini). on pre-2.34 versions of libc, it is not valid for init to be NULL.

2. libc version 2.34 and later can handle init being set to NULL, and someone thinks this can be used in future as some sort of version signalling. exactly how, i am not quite sure, as any application program that set init to NULL would be none-too-bright. it would be similarly reckless to set fini to point to anything other than valid code.

3. compiling an application on an 'old' linux distro seems to be no guarantee that it will work with libc 2.34 and later - at least according to one Jeremy Andrews. this leads me further down the path that our current 'best solution' is a poor one and libc is only sort-of compatible with older binaries.


i wonder if one could use a variation on the concept of UPX, to meld together two quite different blocks of binary code. your application (ELF) binary would be treated as just a block of data packaged up with small 'check and patch' utility - much like a UPXed binary contains an unpacker and the compressed user application. the utility portion would check the libc version installed, and then either run the application from RAM, or, if needsbe, patch then run the application. the  'check and patch' utility could itself be written in pascal as a console application.

this doesn't get around the need to build an 'old' binary, but at least gives some assurance that the correct binary ('old' or 'new') is run.


it is 6am here, so now time for bed... i hope what i've written makes sense in the light of day!

cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on May 21, 2023, 01:43:17 pm
Well, just as others such as Fred Vs mentioned not one of the options to influence the linker seem to be working as intended (at least I was unable to see any changes in the behavior of the linker).

Since I had installed an older debian distro (squeeze) in a VM, I copied some files from there to a separate directory named linklibs (in my project directory on a recent (bookworm) setup):
- ld-2.11.3.so
- ld-linux-x86-64.so.2
- libc-2.11.3.so
- libdl-2.11.3.so
- libm-2.11.3.so
- libpthread-2.11.3.so

I also copied them with removing the version numbers (creating proper links can be done later). In case wondering how to know which files to copy: pass verbosity option to the linker.

Then I copied some example code from the wiki, making use of libc (cthreads to be exact):
Code: Pascal  [Select][+][-]
  1. Program ThreadTest;
  2.  
  3. {test multi threading capability }
  4.  
  5. uses
  6.   {$ifdef unix}cthreads, {$endif} sysutils;
  7.  
  8. const
  9.   threadcount = 10;
  10.   stringlen = 1000;
  11.  
  12. var finished : longint;
  13.  
  14. threadvar thri : ptrint;
  15.  
  16. function f(p : pointer) : ptrint;
  17. var s : ansistring;
  18. begin
  19.   Writeln('thread ',longint(p),' started');
  20.   thri:=0;
  21.   while (thri<stringlen) do
  22.   begin
  23.     s:=s+'1'; { create a delay }
  24.     writeln('thread ',longint(p),' thri ',thri,' Len(S)= ',length(s));
  25.     inc(thri);
  26.   end;
  27.   Writeln('thread ',longint(p),' finished');
  28.   InterLockedIncrement(finished);
  29.   f:=0;
  30. end;
  31.  
  32. var i : longint;
  33. begin
  34.    finished:=0;
  35.    for i:=1 to threadcount
  36.      do BeginThread(@f,pointer(i));
  37.    while finished<threadcount do {nothing} ;
  38.    Writeln(finished);
  39. end.
  40.  

Then tried compile it with:
Code: [Select]
/media/ramdisk/fpc$ fpc -B -k--library-path="/media/ramdisk/fpc/linklibs" -k--trace threadtest.pas

Which ended up for me with:
Code: [Select]
Free Pascal Compiler version 3.2.2 [2021/05/16] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling threadtest.pas
threadtest.pas(81,21) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(85,8) Warning: Local variable "s" of a managed type does not seem to be initialized
threadtest.pas(86,23) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(89,21) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(101,24) Warning: Conversion between ordinals and pointers is not portable
Linking threadtest
/usr/lib/x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/12/crtbegin.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/si_c.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/abitag.o
threadtest.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/system.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/cthreads.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/sysutils.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/objpas.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/linux.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/baseunix.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unix.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unixtype.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/initc.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/dl.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unixutil.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/ctypes.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/errors.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/sysconst.o
/media/ramdisk/fpc/linklibs/libpthread.so
/media/ramdisk/fpc/linklibs/libdl.so
/media/ramdisk/fpc/linklibs/libc.so
/usr/lib/gcc/x86_64-linux-gnu/12/crtend.o
/usr/lib/x86_64-linux-gnu/crtn.o
/usr/bin/ld: /media/ramdisk/fpc/linklibs/libpthread.so: undefined reference to `_dl_make_stack_executable@GLIBC_PRIVATE'
threadtest.pas(104,1) Error: Error while linking
threadtest.pas(104,1) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /home/apps/fpc/3.2.2/bin/x86_64-linux/ppcx64 returned an error exitcode
And that is where I get stuck. Not even a clue as of what it relates to as both libc and libpthread are copied from the same distribution. Could it have to do with the order of linking (and if so is it possible to influence the order) ?

edit:
Figured out that libpthread drags in "ld-linux-x86-64.so.2". Unfortunately it links against the one from my current system that does not have the symbol exported. I seem unable to force the linker to search for the so in another directory.
Code: [Select]
ld-linux-x86-64.so.2 needed by /media/ramdisk/fpc/linklibs/libpthread.so.0
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/ld-linux-x86-64.so.2 failed
attempt to open /usr/local/lib/i386-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /lib/i386-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /usr/lib/i386-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /usr/local/lib/i686-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /lib/i686-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /usr/lib/i686-linux-gnu/ld-linux-x86-64.so.2 failed
attempt to open /usr/local/lib/ld-linux-x86-64.so.2 failed
attempt to open /usr/local/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 failed
found ld-linux-x86-64.so.2 at /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
I have tried all 3 (together as well):
- -k--library-path
- -XR
- -Fl

But unfortunately no changes in the directories the linker is looking in/for  :'(

edit:

On my bookworm I switched out  libpthread.so for the original (squeeze) linker script and adjusted it to read:
Code: [Select]
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /media/ramdisk/fpc/linklibs/libpthread.so.0 /media/ramdisk/fpc/linklibs/libpthread_nonshared.a /media/ramdisk/fpc/linklibs/ld-linux-x86-64.so.2)
Copied required files from squeeze to bookworm linklibs directory

Compiled with:
Code: [Select]
fpc -B -XR/media/ramdisk/fpc/linklibs -k--library-path="/media/ramdisk/fpc/linklibs" -k--trace -Fl"/media/ramdisk/fpc/linklibs" -k-L/media/ramdisk/fpc/linklibs/lib64 threadtest.pas
which outputs:
Code: [Select]
Free Pascal Compiler version 3.2.2 [2021/05/16] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling threadtest.pas
threadtest.pas(81,21) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(85,8) Warning: Local variable "s" of a managed type does not seem to be initialized
threadtest.pas(86,23) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(89,21) Warning: Conversion between ordinals and pointers is not portable
threadtest.pas(101,24) Warning: Conversion between ordinals and pointers is not portable
Linking threadtest
./linklibs/crti.o
./linklibs/crtbegin.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/si_c.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/abitag.o
threadtest.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/system.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/cthreads.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/sysutils.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/objpas.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/linux.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/baseunix.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unix.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unixtype.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/initc.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/dl.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/unixutil.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/ctypes.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/errors.o
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/sysconst.o
/media/ramdisk/fpc/linklibs/libpthread.so
/media/ramdisk/fpc/linklibs/libpthread.so.0
/media/ramdisk/fpc/linklibs/libpthread_nonshared.a
/media/ramdisk/fpc/linklibs/ld-linux-x86-64.so.2
/media/ramdisk/fpc/linklibs/libpthread_nonshared.a
/media/ramdisk/fpc/linklibs/libdl.so
/media/ramdisk/fpc/linklibs/libc.so
./linklibs/crtend.o
./linklibs/crtn.o
/usr/bin/ld: warning: threadtest has a LOAD segment with RWX permissions
104 lines compiled, 0.1 sec
5 warning(s) issued

Copied executable back to squeeze and ran it and instead of the well-known:
Quote
./threadtest
./threadtest: /lib/libc.so.6: version `GLIBC_2.34' not found (required by ./threadtest)

I got:
Code: [Select]
thread 6 started
thread 6 thri 0 Len(S)= 1
thread 6 thri 1 Len(S)= 2
thread 6 thri 2 Len(S)= 3
thread 6 thri 3 Len(S)= 4
thread 6 thri 4 Len(S)= 5
thread 6 thri 5 Len(S)= 6
thread 6 thri 6 Len(S)= 7
thread 6 thri 7 Len(S)= 8
thread 6 thri 8 Len(S)= 9
threathread 8 started
...
thread 1 thri 998 Len(S)= 999
thread 1 thri 999 Len(S)= 1000
thread 1 finished
10
Thus successful, except perhaps for the part that the libpthread linker script needs to be (manually) adjusted. At least you have to do that only once and you would need to set  things up anyhow.

Someone up to figure this out for GUI apps ?  :D
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on June 24, 2023, 08:44:50 pm
This is a proposed solution to the GLIBC_2.34 problem, and is intended for use with FPC 3.2.2 and Lazarus 2.2.6. The method and attached files are experimental and should not at this stage be relied upon when producing binaries for distribution.

There are two parts to the process of preparing FPC/Lazarus (Linux x86_64 only) for generating binaries that are versioned to GLIBC 2.2.5, a version that dates back to 2002:

(1) editing a single line of code in two files located in /usr/share/fpcsrc/3.2.2/rtl, and,
(2) creating a fake libdl.so file that will need to exist in every project directory when you compile an application.

The six symbols we are interested in manipulating are:


(1) The first symbol …
__libc_start_main, is referenced in two files:

For each of the two files we are going to edit a single line that currently reads:
Code: Pascal  [Select][+][-]
  1. procedure libc_start_main; external name '__libc_start_main';

changing it to instead read:
Code: Pascal  [Select][+][-]
  1. procedure libc_start_main; external name '__libc_start_main@GLIBC_2.2.5';

This will force the FPC RTL to be explicitly linked to an earlier version of __libc_start_main (version GLIBC_2.2.5), a version that has existed in libc since around 2002, and is likely to continue to exist for a great many more years. The continuing presence of a complete set of symbols versioned as GLIBC_2.2.5 is what allows old binaries from decades ago to run on new Linux systems - what some folks refer to 'backwards compatibility'. Note that you will need to use root privileges to perform the above edits, as /usr is owned by root.

Once these two files have been edited, we then need to rebuild the FPC RTL, using a shell script that we will place in the FPC source directory, /usr/share/fpcsrc/3.2.2. the shell script ('rebuild.sh') needs to be run with sudo, and contains the lines:
Code: Bash  [Select][+][-]
  1. #!/bin/sh
  2. COMPILER=fpc
  3. make clean
  4. make all FPC=$COMPILER OPT="-Fl/usr/local/lib"
  5. make FPC=$COMPILER install INSTALL_PREFIX=/usr/


(2) The other five symbols ...
dlsym, dladdr, dlclose, dlerror, and dlopen unfortunately need to be handled slightly differently. They are all referenced in the one file:

Just appending '@GLIBC_2.2.5' to each symbol name within dl.pp does not produce a useful result, likely because these symbols have recently been moved from libdl to libc. While the compile-time linker appears to correctly create the Dynamic Symbol Table entries for the symbols, for some reason the run-time linker then only looks for them in libc, even if they exist in libdl; something has not been correctly added to the binary. However, instead creating a fake libdl.so file that is copied into the project directory of each Lazarus project before compiling does work.

When the compile-time linker (invoked by FPC) looks for the above five symbols, the first place it looks (fortuitously) is in our project directory, and when it finds our fake libdl.so file it conveniently uses the five symbols from there. Again, we make those symbols end in @GLIBC_2.2.5.

To create the fake libdl.so file use the two files: libdl.c that contains,
Code: ASM  [Select][+][-]
  1. __asm__(".symver dlopen, __placeholder@@"); // GLIBC_2.2.5");
  2. void dlopen() { }
  3. __asm__(".symver dlsym, __placeholder@@"); // GLIBC_2.2.5");
  4. void dlsym() { }
  5. __asm__(".symver dladdr, __placeholder@@"); // GLIBC_2.2.5");
  6. void dladdr() { }
  7. __asm__(".symver dlclose, __placeholder@@"); // GLIBC_2.2.5");
  8. void dlclose() { }
  9. __asm__(".symver dlerror, __placeholder@@"); // GLIBC_2.2.5");
  10. void dlerror() { }

and libdl.map that contains,
Code: Text  [Select][+][-]
  1. GLIBC_2.2.5 {
  2.   global: dlopen; dlsym; dladdr; dlclose; dlerror;
  3. };


Our fake libdl.so file is built using the command line:
Code: Bash  [Select][+][-]
  1. gcc -Wl,--version-script,libdl.map -fPIC -shared -o libdl.so -Wl,--soname='libdl.so.2' libdl.c


Note that the fake libdl.so file only needs to be present when compiling the project. You do not need to distribute it with your binary. It has the sole purpose of guiding the linker at compile time.


cheers,
rob   :-)


addendum: check the versioned symbols in your binary file using:
Code: Bash  [Select][+][-]
  1. readelf --dyn-syms -W project1 | grep "GLIBC"
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on June 25, 2023, 11:58:06 pm
... and here is an even simpler variation that does not require making any changes to the FPC RTL, however it does leave all six of the symbols unversioned in your application's Dynamic Symbol Table. i am undecided if this is, or is not, a bad thing.

Create a fake libdl.so file using the following libdl.c:
Code: C  [Select][+][-]
  1. void dlopen() { }
  2. void dlsym() { }
  3. void dladdr() { }
  4. void dlclose() { }
  5. void dlerror() { }
  6. void __libc_start_main() { }

Build the fake libdl.so file using the command line:
Code: Bash  [Select][+][-]
  1. gcc -fPIC -shared -o libdl.so -Wl,--soname='libdl.so.2' libdl.c

Now just place the fake libdl.so into your project directory before compiling. Nothing more is required.


You can check the versioned symbols in your binary file using:
Code: Bash  [Select][+][-]
  1. readelf --dyn-syms -W project1 | grep "GLIBC"

And for the other stmbols we have changed with:
Code: Bash  [Select][+][-]
  1. readelf --dyn-syms -W project1 | grep "dl"
and:
Code: Bash  [Select][+][-]
  1. readelf --dyn-syms -W project1 | grep "__libc_start_main"


Note that the fake libdl.so file only needs to be present when compiling the project. You do not need to distribute it with your binary. It has the sole purpose of guiding the linker at compile time.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 26, 2023, 12:23:13 am
... and here is an even simpler variation that does not require making any changes to the FPC RTL, however it does leave all six of the symbols unversioned in your application's Dynamic Symbol Table. i am undecided if this is, or is not, a bad thing.
...

It is a fantastic thing!  ;D

Works perfectly, using unversioned will take the last one from the library.
Tested with the fake library in the root directory of the project and compiled that Lazarus project on XUbuntu 23.04 (GLIBC_2.34).

And tested the binary on a VM old Debian 10: works out of the box.

Well done Rob.   ;)

Hum, about __libc_start_main(), does anybody knows when it is called? (apart in si_g.inc and si_c.inc there are methods that call __libc_start_main() but that methods are never used, nor in fpc, rtl or Lazarus, afaik).
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on June 26, 2023, 09:59:55 pm
Hum, about __libc_start_main(), does anybody knows when it is called? (apart in si_g.inc and si_c.inc there are methods that call __libc_start_main() but that methods are never used, nor in fpc, rtl or Lazarus, afaik).

These are the entrypoints of the generated ELF binaries and they call __libc_start_main to initialize the C library.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 26, 2023, 10:24:03 pm
Hum, about __libc_start_main(), does anybody knows when it is called? (apart in si_g.inc and si_c.inc there are methods that call __libc_start_main() but that methods are never used, nor in fpc, rtl or Lazarus, afaik).

These are the entrypoints of the generated ELF binaries and they call __libc_start_main to initialize the C library.

Ha, ok, thanks (not sure to understand, so it is not called by fpc but systematically by the entrypoints of the ELF ?  :-\)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on June 26, 2023, 11:00:58 pm
Hum, about __libc_start_main(), does anybody knows when it is called? (apart in si_g.inc and si_c.inc there are methods that call __libc_start_main() but that methods are never used, nor in fpc, rtl or Lazarus, afaik).

These are the entrypoints of the generated ELF binaries and they call __libc_start_main to initialize the C library.

Ha, ok, thanks (not sure to understand, so it is not called by fpc but systematically by the entrypoints of the ELF ?  :-\)

It's what is called by either the OS or the dynamic loader (depending on whether it's a dynamic binary or not) and what is located in the ELF binary's entrypoint field.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 26, 2023, 11:44:58 pm
Hum, about __libc_start_main(), does anybody knows when it is called? (apart in si_g.inc and si_c.inc there are methods that call __libc_start_main() but that methods are never used, nor in fpc, rtl or Lazarus, afaik).

These are the entrypoints of the generated ELF binaries and they call __libc_start_main to initialize the C library.

Ha, ok, thanks (not sure to understand, so it is not called by fpc but systematically by the entrypoints of the ELF ?  :-\)

It's what is called by either the OS or the dynamic loader (depending on whether it's a dynamic binary or not) and what is located in the ELF binary's entrypoint field.

Hum, ok, I have to study that deeper, thanks Sven.

May I ask your thinking about the solution of Robert?
This solution is to add a fake libdl.so with unversionned symbol, in the root directory of the project and, at linking, force the linker to use that unversionned symbols vs the one from the library?

All the test that I have done are perfectly ok, compiled with last glibc-2.34 and run even on older glibc-2.9, perfectly out-of-the-box.
But could it be a a hidden bomb somewhere?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: PascalDragon on June 27, 2023, 09:55:23 pm
May I ask your thinking about the solution of Robert?

We are not interested in such solutions. The current way is how code/binaries are supposed to behave on Linux and we'll not change that.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 27, 2023, 10:22:36 pm
May I ask your thinking about the solution of Robert?

We are not interested in such solutions. The current way is how code/binaries are supposed to behave on Linux and we'll not change that.

 :D, I am so surprised!

OK, thanks for that deep thinking. 
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on June 28, 2023, 12:50:08 am
:D, I am so surprised!

OK, thanks for that deep thinking.
It was clear before even 'targeting' this issue that it will not find it's way back to the FPC source-tree. And that is not so strange as it is Linux itself who provided us with this mess. So the thing that FPC needs to do (at a minimum) is follow the lead.

I think Robert realized that as well early on and is/was happy enough to be able to have an alternative solution and be able to provide some patches that you can run over your existing FPC source-tree in case you wish to use his solution/approach. I am happy with my own approach as that is more in line with what Linux seem to dictate us. Different minds, different answers/solutions so I can't say I blame anyone for not integrating something that isn't generally accepted.

It is just what it is and if not mistaken you've dealt with such things in the past before (mse etc).
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 28, 2023, 01:23:01 am
So the thing that FPC needs to do (at a minimum) is follow the lead.

But that is the magical of Robert solution!
No touch to FPC code, let FPC do his right and perfectly understood way.

But, for users who want to have a "universal" binary, use the tools that Linux and his linker give, to link with unversioned symbols.
And to do that, one of the trick is to add a "fake" libdl.so in the directory of the project and compile the project, the linker will use the unversioned symbols of the fake libdl.so.
Nothing more.

Not a single unit from FPC is changed, nor in RTL nor in Lazarus.

I totally understand that there are other way, maybe more Catholic, but the Robert-trick is wow, no need to install a VM and everything.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on June 28, 2023, 04:54:50 am
But that is the magical of Robert solution!
No touch to FPC code, let FPC do his right and perfectly understood way.
I think you misunderstood. Robert's solution most definitely requires for Free Pascal source-code to be touched.

Quote
Not a single unit from FPC is changed, nor in RTL nor in Lazarus.
Ah, and where do you think those include-files that Robert proposes to be changed actually get included ? If you guessed the Free Pascal RTL then your are correct. That requires a complete rebuilt of all your units and compiler. They can not be used interchangeable with non patched units.

Perhaps that provides a better view of/for some people standpoints ?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on June 28, 2023, 05:31:33 am
Fred vS is correct.

the first solution post i made involved edits to the FPC RTL, resulting in the six symbols of interest ending up versioned as GLIBC_2.2.5.

HOWEVER, the followup post i made https://forum.lazarus.freepascal.org/index.php/topic,58888.msg483626.html#msg483626 (https://forum.lazarus.freepascal.org/index.php/topic,58888.msg483626.html#msg483626) shows how a result can be achieved with just a fake libdl.so file sitting in your project's directory and nothing more.

this far simpler solution removes all versioning from the set of symbols. this is a slightly more unconventional approach, but i feel that the fixed nature of the FPC RTL's use of libc may mitigate concerns. it ensures that your application, at run-time, is using the latest set of symbols available on each individual machine it is run on.

i have made enquiries with the glibc authors on this approach, and am awaiting their reply.

the below fake libdl.c removes all versioning from my test application:

Code: C  [Select][+][-]
  1. // compile with:
  2. // gcc -fPIC -shared -o libdl.so -Wl,--soname='libdl.so.2' libdl.c
  3. //
  4. void dlopen() { }
  5. void dlsym() { }
  6. void dladdr() { }
  7. void dlclose() { }
  8. void dlerror() { }
  9. void __libc_start_main() { }
  10. void wcrtomb() { }
  11. void wcscoll() { }
  12. void strcoll() { }
  13. void mbrlen() { }
  14. void mbrtowc() { }
  15. void iconv() { }
  16. void iconv_open() { }
  17. void iconv_close() { }
  18. void setenv() { }
  19. void setlocale() { }
  20. void sched_yield() { }
  21. void nl_langinfo() { }
  22. void __cxa_finalize() { }
  23. void __errno_location() { }
  24. unsigned int towlower(unsigned int i) { }
  25. unsigned int towupper(unsigned int i) { }


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on June 28, 2023, 05:39:56 am
Ah thank you for pointing out my mistake Robert. I was (still) referring to your post https://forum.lazarus.freepascal.org/index.php/topic,58888.msg483544.html#msg483544 when I wrote my reply. I'll have to check that  :) thank you for the continues contribution on the subject.

My apologies to Fred vS (and you Robert), I am/was wrong there.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: DonAlfredo on June 28, 2023, 07:38:53 am
This approach might (also) be useful for fpcupdeluxe, when cross-compiling towards Linux.
I will do some testing.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: DonAlfredo on June 28, 2023, 09:04:40 am
Linking with your custom libdl.c works well.
In my case, I needed few more extras:
void openlog() { }
void closelog() { }
void syslog() { }
void sysconf() { }
If above added, the cross-compiled fpcupdeluxe linux binary is fully GLIBC-unversioned !
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 28, 2023, 02:07:45 pm
Linking with your custom libdl.c works well.
In my case, I needed few more extras:
void openlog() { }
void closelog() { }
void syslog() { }
void sysconf() { }
If above added, the cross-compiled fpcupdeluxe linux binary is fully GLIBC-unversioned !

Fantastic!

@Rob:  ;)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on June 28, 2023, 02:30:34 pm
I think this is a seriously important development !

It really needs a wiki page rather than risking getting lost in the steady roll out of forum posts. It will not be that long before the OS Systems that will not run a binary compiled on a new system are themselves no longer supported and the excitement here will die down.

But it will happen again, something will be changed again in glibc and people will again have this problem. So, a record of this excellent work must be readily available in the wiki for it to be reapplied.

Robert, do you want to write a Wiki page, maybe called, simply, "glibc symbols" or something similar ?

Congratulations to all involved in this project !   (I readily confess I thought it was a dead end, Wrong!)

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 28, 2023, 03:47:39 pm
It is just what it is and if not mistaken you've dealt with such things in the past before (mse etc).

Hard to be the Jiminy Cricket of FPC.  ::)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on June 28, 2023, 04:12:11 pm
Robert, do you want to write a Wiki page, maybe called, simply, "glibc symbols" or something similar?

i would be happy to help with writing a wiki page, however my knowledge of glibc symbols is pretty much summed up in what has been presented here. i am far from an expert, and proceeded mostly through trial-and-error hacking away at a problem i had a hunch should be solvable. the major breakthrough actually occurred when another forum member emailed that he had added __libc_start_main to the library libdl.so where it did not belong. it was from there that i guessed what was going on - that when the glibc developers (as of glibc 2.34) merged the functionality of libdl.so into libc.so they had to leave a 'back door' for older binaries to continue working, in the form of a placeholder libdl.so that simply 'handed symbols on' to the new expanded libc.so.

now that we know what is possible, much more widespread testing is needed. we need to discover the limitations introduced with unversioned symbols, and look at ways to catch any resulting errors at run-time. this requires cooperation from the experts - the FPC developers. they know the inner workings of FPC's RTL far better than anyone else, and the how and why of the RTL's use of libc functions.

there is also the interesting question of: why are libc functions so widely bound to using EXTERNAL? certainly it makes for simple one-line code, but could one not equally well use a combination of dlopen('libc.so.6', flags) and dlsym()? in one fell swoop this could considerably shrink the list of symbols in a binary's Dynamic Symbol Table to... just three (__libc_start_main, dlopen, and dlsym).


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: sketch on June 28, 2023, 06:57:11 pm
In the version file
Code: [Select]
GLIBC_2.2.5 {
  global: dlopen; dlsym; dladdr; dlclose; dlerror;
};

Why not just wildcard it?
Code: [Select]
GLIBC_2.2.5 {
  *;
};
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 28, 2023, 07:08:02 pm
In the version file
Code: [Select]
GLIBC_2.2.5 {
  global: dlopen; dlsym; dladdr; dlclose; dlerror;
};

Why not just wildcard it?
Code: [Select]
GLIBC_2.2.5 {
  *;
};

With the last solution, no need anymore of the map file.  ;D
https://forum.lazarus.freepascal.org/index.php/topic,58888.msg483626.html#msg483626
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: sketch on June 28, 2023, 07:57:03 pm
however it does leave all six of the symbols unversioned in your application's Dynamic Symbol Table.

Create a fake libdl.so file using the following libdl.c:
Code: C  [Select][+][-]
  1. void dlopen() { }
  2. void dlsym() { }
  3. void dladdr() { }
  4. void dlclose() { }
  5. void dlerror() { }
  6. void __libc_start_main() { }
A version script has three purposes:

* Define versions.
* Specify some patterns so that matched defined symbols (which do not have @ in the name) are tied to the specified version.
* Scope reduction
   * for a matched symbol, its binding will be changed to STB_LOCAL and will not be exported to the dynamic symbol table.
   * for a defined unversioned symbol, it can be matched by a local: pattern in any version node. E.g. foo can be matched by v1 { local: foo; };
   * for a defined versioned symbol, it can be matched by a local: pattern in the associated version node. E.g. both foo@@v1 and foo@v1 can be matched by v1 { local: foo; };.

Since it's an ABI change, don't you want to use a version file and so it won't be exported to the dynamic version symbol table?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on June 28, 2023, 10:43:22 pm
* Scope reduction

1. it is a fake libdl.so file, the code within is never executed. the file exists purely to guide the linker at compile-time towards arriving at a particular conclusion - that the symbols therein should be unversioned.

2. our goal is not scope reduction, but instead scope expansion. this expansion only avoids ending in tears because the original scope reduction was done to achieve purely philosophical objectives that lacked any useful intersection with the real world.

3. please stop using ChatGPT to generate your postings. perhaps i am being a bit harsh, but your posts do seem to be coming from way off left field.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: sketch on June 29, 2023, 03:17:17 pm
I don't use ChatGPT, Einstein. So go fuck yourself. Delete this comment if you want, but I'll never know because I am never coming back here and refuse to let some elitist piece of shit talk down to me.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 29, 2023, 03:53:18 pm
@sketch.

Everybody, not only you, who have participated to this topic, is hyper-stressed.

Fisrt those who did try to solve the problem.
It is a hard battle, if fact, even the fpc team is helpless in the face of the goodwill of the glibc developers.

Your post may have felt like a misguided attempt to only annoy and maybe the reader was in bad mood.
Please, try to do like all of us try to do, breathe calmly, think about something else and still remain creative and open-mind.

Your contribution is precious, dont forget we are all in the dark.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Lulu on June 29, 2023, 07:53:55 pm
Hi, I thanks you all of your, because I'm know programming in Pascal but I'm not aware about what append in the backstage of the compiler/linker. Reading all this discussion was VERY constructive for me ! Actually, I can say that about the whole Lazarus forum.
And I say that in all sincerity.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on June 29, 2023, 09:09:28 pm
Delete this comment if you want, but I'll never know because I am never coming back here and refuse to let some elitist piece of **** talk down to me.

my apologies, i had detected a certain style in your posting that had triggered my ChatGPT 'detector', quite falsely as it turns out. i have now read through your other forum postings, and it seems to just be a writing style thing; i found your comments on left-pad and layers of abstraction highly interesting. a search with google revealed a good background: https://qz.com/646467/how-one-programmer-broke-the-internet-by-deleting-a-tiny-piece-of-code (https://qz.com/646467/how-one-programmer-broke-the-internet-by-deleting-a-tiny-piece-of-code).

when someone writes with detailed examples and an extremely even timbre these days, i tend to be suspicious. coupled with a toothache that has been with me for nearly a week (am off to the dentist in a few hours), and i did respond without due deliberation. again, my apologies.

from your past postings on the forum it does look like you have some knowledge of how map files work - if you could figure out how to version __libc_start_main to GLIBC_2.2.5 using just the fake libdl.so that would 'close the circle' on the GLIBC 2.34 problem. it evaded me, hence the need to edit the FPC RTL to handle that one symbol. unversioning everything, as you've noticed, was far easier.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 30, 2023, 12:25:50 am
Hello.

I did lot of search, Googling "glibc unsigned symbol", "glibc signed symbol" etc.
Nothing interesting or nothing to do with.

So, I did something very bad, everybody will hate me, including you Robert and Sketch.
I did ask to the horrible ChatGPT:

Q:
Quote
Hello. About libc.so and symbols table. A signed symbol is for example @GLIBC_2.2.5. What happen if no symbols are assigned. That table is used at linking of programs.

A:
Quote
In the context of the GNU C Library (glibc), symbol versions are used to manage changes in the library's interfaces over time. Each symbol in the library is assigned a version, such as "@GLIBC_2.2.5" as you mentioned.

When a program is linked against the glibc, the linker will resolve the symbols used by the program to their corresponding implementations in the library. If a symbol is assigned a specific version, such as "@GLIBC_2.2.5", it means that the program requires that particular version of the symbol or a newer version.

If a symbol is not assigned any version, it means that the program does not have a specific requirement for that symbol's version. In such cases, the linker will link the program to the default version of the symbol provided by the glibc at runtime. This allows the program to work with any compatible version of the symbol.

However, it's important to note that if a program uses a feature or functionality that is only available in a specific version of a symbol, and that version is not provided by the glibc at runtime, the program may fail to run correctly or may encounter compatibility issues.

To summarize, if no version is assigned to a symbol in glibc, the linker will link the program to the default version of the symbol provided by the glibc at runtime.

I am ashamed.  :-[

[EDIT] And I did continue, sure I am already to hell.  :-X

Q:
Quote
Does it exist a command parameter for the linker to force to link all the methods unversionned of libc.so and let all other libraries with no change?

A:
Quote
Yes, there is a linker option that can be used to force the linker to resolve all symbols without version dependencies. The linker option is called `--version-script` or `-Wl,--version-script`, depending on how it is passed to the linker.

The `--version-script` option allows you to provide a script that specifies the version dependencies for symbols. By default, if no version script is provided, the linker will use the default version script, which includes version dependencies for symbols.

To force the linker to ignore version dependencies and link all symbols unversioned, you can create a version script file that includes a wildcard pattern for symbols and use that as an argument to the `--version-script` option. For example:

```shell
$ ld --version-script=unversioned.lds -o your_program your_object_files.o
```

Here, `unversioned.lds` is a text file containing the version script. You can define a wildcard pattern in the version script to match all symbols, like this:

```
{
  global:
    *;
};
```

This version script specifies that all symbols should be considered global and can be resolved without version dependencies.

By using this approach, you can override the default version script and force the linker to link all symbols unversioned, effectively ignoring any version dependencies.

Please note that modifying the versioning behavior of symbols should be done with caution, as it may lead to compatibility issues or unexpected behavior in your program. It's important to ensure that your program is compatible with the versions of symbols it is linked against.

Q:
Quote
And if I want to assign only some methods unsigned in libc.so, for example __libc_start_main

A:
Quote
If you want to assign only specific symbols, such as `__libc_start_main`, as unsigned in `libc.so`, while leaving other symbols with their version dependencies intact, you can use a custom version script.

Here's an example of how you can achieve this:

1. Create a version script file, let's call it `libc_custom.lds`, with the following contents:

```text
GLIBC_2.2.5 {
  global:
    __libc_start_main;
  local:
    *;
};
```

In this version script, `GLIBC_2.2.5` is an example version, and `__libc_start_main` is the symbol you want to assign as unsigned. All other symbols in `libc.so` are designated as local, which means their version dependencies will be preserved.

2. Then, use the `--version-script` option to specify the custom version script during the linking process:

```shell
$ ld --version-script=libc_custom.lds -o your_program your_object_files.o -lX -lY -lc
```

This will link your program (`your_program`) with `libc.so` (`-lc`), while assigning `__libc_start_main` as unsigned.

[EDIT] I did try to link with `--version-script` option ( after using -sh fpc parameter to create the script and create the script for --version-script ) but it did not work for me, some methods of libc.so are still 2.34.

That said, if it is possible to do it with a script to the linker it would be good too. (but till now only the fake libdl.so is working).
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on June 30, 2023, 02:57:34 am
.....
I am ashamed.  :-[


This is, of course, the sort of thing that lead inexorably to the fall of the Roman Empire.

Oh well Fred, as long as you asked ChatGPT for a clear license statement, we could use some of it on a wiki page, its well put together .....

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 30, 2023, 04:08:34 am
.....
I am ashamed.  :-[


This is, of course, the sort of thing that lead inexorably to the fall of the Roman Empire.

Oh well Fred, as long as you asked ChatGPT for a clear license statement, we could use some of it on a wiki page, its well put together .....

Davo

Yes, but, as usual with ChatGPT, sometime it is right, sometime less.
The first part explaining the unversioned symbols seems plausible.

But his solution for linking using parameter ld --version-script=unversioned.lds, for me, does not work.
So Robert solution dont have yet challenger.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on June 30, 2023, 09:11:28 am
Ha, I did not read your edit addition. That would be just like ChatGP, state an authorative, clear, easy to implement, cheap solution (that does not work) !

But I did like the initial summary.

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on June 30, 2023, 11:07:42 am
my feeling is that glibc is using symbol versioning for different reasons to what one might think. consider the example from http://peeterjoot.com/2019/09/20/an-example-of-linux-glibc-symbol-versioning/ (http://peeterjoot.com/2019/09/20/an-example-of-linux-glibc-symbol-versioning/):

void foo1( int x )
{ ... }
void foo2( int x, int y )
{ ... }


very basically, we have a function within our library, foo(), that has two different APIs. using a map file we can persuade the linker to map foo() to foo1() or foo2() depending upon the version of foo() selected at compile-time by either the linker or the user program.

but in the case of FPC's RTL and glibc this selection is based solely upon the most recent version of each function available at compile time - generally GLIBC_2.2.5 or GLIBC_2.34. furthermore, FPC's RTL has no knowledge of different APIs that may exist for any of the glibc functions it uses.

so this begs the question: if our Lazarus/FPC program has no knowledge of multiple different APIs for some glibc functions (and IF such differing APIs even exist in practice), what purpose does the symbol versioning serve in the context of Lazarus/FPC?!

it seems to me that the sole purpose is so that we can assert "has been run and tested against this specific glibc version". and this only works because every version of glibc contains the complete API of every prior version of glibc, along with any of its own API additions.

while some might also surmise that versioning in GLIBC is also a useful mechanism to forcefully obsolete older linux systems, well i couldn't possibly comment on that...


cheers,
rob   :-)


Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 30, 2023, 02:57:36 pm
so this begs the question: if our Lazarus/FPC program has no knowledge of multiple different APIs for some glibc functions (and IF such differing APIs even exist in practice), what purpose does the symbol versioning serve in the context of Lazarus/FPC?!

Because when the FPC team did the implementation of RTL-glibc, ChatGPT did not exist yet, so nothing to help/explain how versioned symbols work and for what it is used. Also FPC is terrified by the linker ld() (versioned symbols, extended soname, ...).  :-X

They prefer discuss the gender of aliases than worry about user real issues.

By the way, does it exist a FPC parameter to add a custom parameter to the linker?

Yes, I am in bad mood after the anthological "We are not interested in such solutions. The current way is how code/binaries are supposed to behave on Linux and we'll not change that."

Dont forget that, if FPC is still alive, it is not only thanks to the FPC devs but also thanks to the many passionate who give code, help, libraries, tools, programs, hours of their time, ...

They should be cherished rather than treated with disdain.

Fre;D
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on June 30, 2023, 08:35:27 pm
The libc RTL was created on FreeBSD, though Linux was only weeks later. Yet later again it was made default on OS X and iirc Solaris.

Symbol versioning was not considered, for the simple reason that most difficult calls take structures (stat etc). And Pascal record definition don't automatically change due to linker scripts

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on June 30, 2023, 08:40:13 pm
Symbol versioning was not considered,

OK so why not use symbol unversioned?

Maybe you could change the slogan with this: FPC write once, compile everywhere and run only where it was compiled (or on exactly the same OS).

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 01, 2023, 06:06:59 am
The libc RTL was created on FreeBSD, though Linux was only weeks later. Yet later again it was made default on OS X and iirc Solaris. Symbol versioning was not considered, for the simple reason that most difficult calls take structures (stat etc). And Pascal record definition don't automatically change due to linker scripts

given that symbol versioning was not considered when the RTL code was created, can one safely assume that the present versioning situation is purely driven by the folks who write the Lazarus/FPC linker scripts?

it is looking like, if desired, a relatively small tweak to the linker scripts used during the compiling of a user program could eliminate symbol versioning. is it therefore correct to say that the maintainers of those linker scripts have the knowledge of how to do this, but said maintainers choose to not share that knowledge. i personally see this is a version of security by obscurity.

btw: i have no idea how to change the linker scripts myself. would any of the Lazarus/FPC developers reading this care to share the knowledge?


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 01, 2023, 06:12:46 am
FPC [...] and run only where it was compiled (or on exactly the same OS)

this is the major weakness of Lazarus/FPC on x86_64 platforms. building for Debian/GTK2 yields a binary that can run on, by my estimate perhaps 70% of x86_64 desktop platforms out there. however, symbol versioning erodes that 70% considerably, and for what seems like no gain.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on July 01, 2023, 06:29:23 am
btw: i have no idea how to change the linker scripts myself.

Afaik, that can only be done with the -sh fpc parameter.
You will get a ppas.sh script and linkxxx.res resource file.
Edit the ppas.sh script and change with what you want then, in console, in the same directory as the project, run bash ppas.sh, it should link all the fpc objects.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on July 01, 2023, 04:18:09 pm
Symbol versioning was not considered,

OK so why not use symbol unversioned?

With FPC 3.0 to support native resources a linker script was introduced. But that is not RTL, that is the compiler linking backend.  You can see in rtl/unix/oscdeclh.inc that the RTL uses all names are undecorated with versioning info.

In short, get your facts straight, and write a good summary. Linux changes all the time, and you all might have a point. But you do a shitty job in getting it across. Best would be to write a patch to run the system the way you seem fit, and preferably build a binary release with it. Then you can ask around if this improves compatibility.

Quote
Maybe you could change the slogan with this: FPC write once, compile everywhere and run only where it was compiled (or on exactly the same OS).

Incendiary remark, which is pointless and uncalled for.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on July 01, 2023, 05:03:45 pm
With FPC 3.0 to support native resources a linker script was introduced. But that is not RTL, that is the compiler linking backend.  You can see in rtl/unix/oscdeclh.inc that the RTL uses all names are undecorated with versioning info.

Maybe (dont worry I will deeply study it) but the fact is, at the present, the binary is versioned and makes the binary only usable on the same OS as where it was linked.

Quote
Maybe you could change the slogan with this: FPC write once, compile everywhere and run only where it was compiled (or on exactly the same OS).

Incendiary remark, which is pointless and uncalled for.

Without fire, you dont move Marco and the remark is maybe pointless and uncalled for but is the reality.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 01, 2023, 05:32:50 pm
With FPC 3.0 to support native resources a linker script was introduced. But that is not RTL, that is the compiler linking backend.  You can see in rtl/unix/oscdeclh.inc that the RTL uses all names are undecorated with versioning info

i have just spent an evening playing round with the -sh parameter that Fred vS mentions, and the resulting ppas.sh and linknnnnn.res files generated. i can confirm that there is not much that can be done with them to affect versioning in the final binary. i've also just gone through /usr/share/fpcsrc/3.2.2/rtl/unix/oscdeclh.inc and can confirm both that (a) there is no versioning in there, and also that (b) all symbols included in a linux build reference to libc. for me, the libc bit is an important point, as that is what the libdl.so solution targets.

i also tried the suggestion quoted by Fred vS from ChatGPT:
Quote from: ChatGPT
Yes, there is a linker option that can be used to force the linker to resolve all symbols without version dependencies. The linker option is called `--version-script` or `-Wl,--version-script`, depending on how it is passed to the linker
[...]
To force the linker to ignore version dependencies and link all symbols unversioned...

while i am in no way an expert, as far as i have been able to determine the response from ChatGPT is a jumble of disconnected statements that taken as a whole are nonsense. portions are specific to creating dynamic libraries, and hence not even applicable. please do correct me if i am wrong.

In short, get your facts straight, and write a good summary. Linux changes all the time, and you all might have a point. But you do a s****y job in getting it across

i agree 100%. but surely you must realize that we are a bunch of amateurs, all speaking different languages, flailing away with no direction and a dearth of information. quite a lot of what we are doing is just making guesses; trying every combination until something seems to lead a little closer to a solution. PascalDragon has made it pretty clear that he has no intention of helping, and, to be honest, has blithely watched us all go down several dead-end tracks and said nothing. his statement, "We are not interested in such solutions. The current way is how code/binaries are supposed to behave on Linux and we'll not change that", stands as coming from the FPC developers as a whole, and that has left folks feeling, well... angry.

Best would be to write a patch to run the system the way you seem fit, and preferably build a binary release with it. Then you can ask around if this improves compatibility

already done, in the form of the libdl.c file i've posted. it works, it solves the problem. the only improvement would be to gain a complete list of libc functions needing to be handled. if the Lazarus/FPC developers wanted to add something to the IDE where the build process automatically created the libdl.so file before linking, linked, then deleted the libdl.so file, then all well and good. personally, i couldn't care less if they do or don't. at the moment all i'm interested in is hearing back on success and failures in using the solution out in the real world.

but i would appreciate seeing a little help and guidance from the Lazarus/FPC developers. we are all, supposedly, trying to work towards the greater good.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: DonAlfredo on July 01, 2023, 05:45:16 pm
Interesting reverse argument mentioned here.
https://sourceware.org/pipermail/libc-alpha/2021-October/132168.html

Sidenote.
I have never received glibc versioning complaints about fpcupdeluxe. Now that an unversioned version is out, it will be interesting to get feedback, if any.

New.
This is the most recent issue up-issue.
https://github.com/LongDirtyAnimAlf/fpcupdeluxe/issues/595
Its an glibc versioning error regarding the cross-tools that are provided (and build by me, on some Linux system).
It happens often with the tools that are provided by fpcupdeluxe.
I am now setting up Ubuntu16 for the binary tools. But its not that easy for tools based on clang.
Just FYI.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 01, 2023, 05:47:43 pm
@robert
On top of what you already wrote note that in principle FPC already has proficiency for the issue at hand in the form of handling it as cross-compiling. Also chrooting is possible. Not exactly what you had in mind but those options do exist making it probably less interesting to have a look at other solutions/approaches.


already done, in the form of the libdl.c file i've posted. it works, it solves the problem. the only improvement would be to gain a complete list of libc functions needing to be handled. if the Lazarus/FPC developers wanted to add something to the IDE where the build process automatically created the libdl.so file before linking, linked, then deleted the libdl.so file, then all well and good.
Note that at least for Lazarus you are allowed before a build or compilation (but also after) you can invoke a custom exe or script to realize something like that manually yourself. It is not ideal but does make life a bit easier as the option is available. Using a fpc script (or a custom made frontend for fpc) for compilation  allow you to do something similar (which then also automatically applies for Lazarus as long as you use the same script).

But you should be able to compile against a custom libdl using some options as well but I still have not come to try that with your solution.

As for expressed sentiments: note that it is not the FPC team (or anyone/thing related to FPC) causing the issues here. It is the OS that dictates so any frustration/anger directed to other than those OS developers making the actual decisions is imho misplaced.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Fred vS on July 01, 2023, 07:41:52 pm
But you do a shitty job in getting it across.

Hey, clean best friend, you just appear now, after 11 pages in the topic, with more than 16840 views, for a problem with your code, letting other devs defend your s***y code.   >:(
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: circular on July 01, 2023, 08:21:39 pm
I am a bit sad of seeing valuable people around Pascal having a go.

I honestly don't understand fully the topic, though I do understand two things:
- versioning is a bit complicated and it seems a leap into the unknown to play this it
- even though it is how Debian distributions are organized, it is not reasonable for independent developers to build for different versions

I am sure we can talk about this with more flexibility and care.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on July 01, 2023, 08:59:06 pm
With FPC 3.0 to support native resources a linker script was introduced. But that is not RTL, that is the compiler linking backend.  You can see in rtl/unix/oscdeclh.inc that the RTL uses all names are undecorated with versioning info.

Maybe (dont worry I will deeply study it) but the fact is, at the present, the binary is versioned and makes the binary only usable on the same OS as where it was linked.

Maybe that is the OS default? But as said, you need to do research, not pointing at loose sand and cry wolf. If it is wrong, what is wrong? Which linker parameter? What line in the script ?




Quote
Incendiary remark, which is pointless and uncalled for.

Without fire, you dont move Marco and the remark is maybe pointless and uncalled for but is the reality.

This is not my topic anyway, as my *nix use is fairly low nowadays (and I was always more FreeBSD than Linux)

As said I did the RTL back in 2003, and the basic design is still there. This is not the RTL, this is the linker and/or its instrumentation

Anyway, start documenting experiences and reproduction, and try to evaluate across the board (not just a few calls and 2 distros). 

We got exactly this same discussion several times with glibc vs syscall, but in the end we never received a thorough evaluation, just random emotion. And in that case we were prepared for it, as the -dFPC_USE_LIBC rtl was added for that exact  reason.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 01, 2023, 09:26:12 pm
Anyway, start documenting experiences and reproduction, and try to evaluate across the board (not just a few calls and 2 distros)

i am sitting back and waiting for the flood of users reporting their successes and failures   :(   i assume there are forum members who do actually write programs?!

We got exactly this same discussion several times with glibc vs syscall [...] we were prepared for it, as the -dFPC_USE_LIBC rtl was added for that exact  reason

just did a grep for "syscall" on /usr/share/fpcsrc and was pleasantly surprised at the volume of matches!

am i then right in saying that FPC uses syscalls for the majority of functionality, and libc only if there isn't a syscall alternative? these minority cases (predominantly) being threading and loading libraries (dlopen et al)?

are there realistic alternatives out there to using glibc/libc for threading and loading libraries?


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: DonAlfredo on July 01, 2023, 09:50:00 pm
This might help a tiny bit.
https://github.com/wheybags/glibc_version_header
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on July 01, 2023, 10:57:19 pm
Anyway, start documenting experiences and reproduction, and try to evaluate across the board (not just a few calls and 2 distros)

i am sitting back and waiting for the flood of users reporting their successes and failures   :(   i assume there are forum members who do actually write programs?!

More like formulating their exact problem. But yes, in essence. It is a community project.

am i then right in saying that FPC uses syscalls for the majority of functionality, and libc only if there isn't a syscall alternative?

Yes. Keeps the core RTL and thus relative simply programs free of libc.

Quote
these minority cases (predominantly) being threading and loading libraries (dlopen et al)?

Anything beyond simple programs, though 1.0.x had some threading based on the rfork/Clone() call. (which sucked by the way).

Quote
are there realistic alternatives out there to using glibc/libc for threading and loading libraries?

Not that I know. Everything has gotten progressively complicated over the years. Threading got overhauled multiple times in Linux with 2.2 and again with 2.4.x
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: circular on July 02, 2023, 09:01:55 am
Is there any drawback linking to an older version of libc? I guess it would be safer in a way than no versioning because we would be assured of the signatures of the functions.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: circular on July 02, 2023, 09:13:45 am
Q: We would like to build programs that use some functions of libc, in particular to load libraries dynamically. But when linking, the binary is linked to latest version of libc and this makes it unusable on older distros.

GPT4: When you're developing a program that should be able to run on multiple different Linux distributions, including older ones, it's often important to pay attention to the versions of the libraries that your program depends on. This is because if your program is built with a newer version of a library, it may not work correctly (or at all) on a system that has an older version of that library.

In your case, your program depends on the GNU C Library (glibc), but you're running into issues because the program is being built with a version of glibc that's too new for some of the systems you want to support.

One solution to this problem is to build your program on the oldest system you plan to support. This is often a good approach because glibc is backwards compatible (i.e., newer versions of glibc maintain compatibility with older versions). Therefore, a binary that's built with an old version of glibc should work on systems with newer versions of the library.

Here are some steps to do it:
Another option, though more complex, is to statically link your program with the libraries it needs. However, static linking has its own set of complexities and potential issues (like bloated binary size, security issues because of not receiving updates to libraries etc.), so it's usually not the preferred solution for most applications.

Remember, if you use additional libraries, ensure they follow the same compatibility as the oldest version of glibc you are targeting.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on July 02, 2023, 03:26:17 pm
Well, ChatGPT is roughly right. Note that this kind of advice is the typical answer you ask this in maillists/forums/newsgroups, and not always based on practical experiences. The fact that it has been the same for 10+ years says enough. Recently Flatpack and the like have been added, and doesn't feature in this answer.

Also keep in mind that keeping some old server app running on a newer system (where the sysadmin is prepared to do some work), is a totally different scenario to a windows-like scenario where you distribute binaries to "customers" that then have to run it on their local system. The server scenario is much less "ready to run".

But building on an older system is the best chance to my best knowledge, but no guarantees. Other solutions have been mentioned, but I haven't seen practical info in ages.

In the distant (2000) past, some hardware like network cards came with statically linked applications to initialize them into some compatibility mode (am not sure anymore but iirc it were NE2000+ aka NE2100 cards), much like the soundblaster inits in good old dos.

An occasional Netscape was also distributed statically linked, but that is all pre-mozilla times.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: circular on July 02, 2023, 04:10:52 pm
It may be more practical, instead of having an old distro, to have a local file for libc as Robert proposed, that presents as an older version. One could thus control the minimum required version.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on July 02, 2023, 04:29:09 pm
It may be more practical, instead of having an old distro, to have a local file for libc as Robert proposed, that presents as an older version. One could thus control the minimum required version.

There are many hypothetical cases, but few on which you can find any practical feasibility information

E.g. I'm not sure if an old libc built on an old and new system would be the same, since the kernel header files would differ. E.g. will it have an old stat record definition, or copy the kernel's ?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: circular on July 02, 2023, 04:39:57 pm
This can be an experimental feature, not applied by default. For example, this could be used/toggled when compiling a DEB file for direct download.

This stat record corresponds to a record defined in FreePascal source?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on July 02, 2023, 05:02:46 pm
This can be an experimental feature, not applied by default. For example, this could be used/toggled when compiling a DEB file for direct download.

This stat record corresponds to a record defined in FreePascal source?

The problem is that if you compile a C program it takes the header from the _system_ to define the stat, and it then matches binary copies of the library compiled on that system. So if stat is defined in the system (kernel) headers rather than glibc sources that might cause problems, both for C and for Pascal.

Because the definition with what the program and libc was compiled (the stat from a later system) wouldn't match the binary copy of the library on the older system that was compiled with the headers of the earlier system.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: circular on July 02, 2023, 05:12:39 pm
I presume this is handled by the legacy version (glibc 2.2.5) of the functions. So I imagine the only thing we need to consider is Pascal's side.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 04, 2023, 05:18:59 am
@robert rozee:

Assuming we can't use FPC itself for creating the library (? haven't tried either) I performed the following steps:

1. Create a fake libdl.so file using following libdl.c
Code: [Select]
void dlopen() { }
void dlsym() { }
void dladdr() { }
void dlclose() { }
void dlerror() { }
void __libc_start_main() { }

2. Build fake libdl.so file with
Code: [Select]
gcc -fPIC -shared -o libdl.so -Wl,--soname='libdl.so.2' libdl.c

3. Placed fake libdl.so to somewhere on my system, as an example /media/ramdisk/patches/robert/fakelibdl

4. Created a small threading example taken from the wiki (https://wiki.freepascal.org/Multithreaded_Application_Tutorial#Pure_FPC_example) naming it threadtest.pas

5. Compiled project with:
Code: [Select]
fpc -B -k--library-path="/media/ramdisk/patches/robert/fakelibdl" threadtest.pas

if you wish to know what is happening during linking stage you can use:
Code: [Select]
fpc -B -k--trace -k--library-path="/media/ramdisk/patches/robert/fakelibdl" threadtest.pas

So far, seems to work as intended. Note that above steps remove the requirement/need to have the fake libdl.so in your project directory. The option can be added to your lazarus project, to your fpc.cfg (f.e. possible by checking for a define to make it optional)  or to your fpc.sh script (I have already incorporated it to be able to compile with fpc -fake -B threadtest.pas)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 04, 2023, 06:24:16 pm
TRon: excellent work. testing as widely as possible is the big thing at the moment, and threading is something that i was worried might not work!


[...] for Lazarus you are allowed before a build or compilation (but also after) you can invoke a custom exe or script to realize something [...]

can these be placed in the fpc.cfg file, so that the script or .exe is invoked for every project without needing to add it via the Lazarus IDE?

i'm thinking of one program (before) that is just a popup that asks "Do you want to use unversioned GLIBC symbols?" and writes the libdl.so file if the yes button is clicked, then another (after) that silently removes the libdl.so file and uses readelf to check that all symbols in the compiled binary are unversioned - if not, it pops up a warning message. i'm currently thinking that automatically adding symbols is a problem, as void name() { } doesn't work for everything. eg towlower and towupper. it may be sufficient to have a copy of libdl.c in a thread on here that people can add to as new symbols that need unversioning are found.


attached is a 5-page writeup on the current state of things. subject to suggestions and corrections - i'm not 100% sure on many things!

dbannon: would this form a suitable basis for a wiki page?

marcov: is this the sort of summary you were thinking of?


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: funlw65 on July 05, 2023, 12:21:22 pm
...

attached is a 5-page writeup on the current state of things. subject to suggestions and corrections - i'm not 100% sure on many things!

dbannon: would this form a suitable basis for a wiki page?

marcov: is this the sort of summary you were thinking of?


cheers,
rob   :-)

I bet it is!

Thank you for the solution. All developers of commercial apps will be affected by this, and not only the Pascal programmers.

I wonder what unthinkable changes are expected in the Linux kernel if such restriction is required to force the future adoption of what is coming...
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: dbannon on July 05, 2023, 01:21:35 pm

dbannon: would this form a suitable basis for a wiki page?
....

Sure, its a serious work, might be a paper in it !

I think I would present, on the wiki page, the solution first, the supporting information can remain in the PDF, accessible from the forum post. Sadly, most users will want a simple solution that works. Few will read past that.

My guess is that the simple solution will encourage more people to test it, probably find problems so, will need refinement but it is a brilliant start. Once its stable, proven, we'll annoy the developers again !

First, I'll try and replicate the system just from your PDF, on a clean system. I am about to head off on a trip in a few days, might be a bit slow I am afraid. If I can make a start, someone else might "collaborate".

Nice work !

Davo
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: funlw65 on July 05, 2023, 02:45:55 pm

dbannon: would this form a suitable basis for a wiki page?
....
...
I think I would present, on the wiki page, the solution first, the supporting information can remain in the PDF, accessible from the forum post. Sadly, most users will want a simple solution that works. Few will read past that.

My guess is that the simple solution will encourage more people to test it, probably find problems so, will need refinement but it is a brilliant start. Once its stable, proven, we'll annoy the developers again !
...

Davo

It wasn't hard to rapidly extract the right information and prepare the solution as described... All people interested in will get it right. Not this is the problem. The thing is, this post is quite "hidden", I would have not known about it if it weren't a person to signal this to me...
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 05, 2023, 04:13:19 pm
Thank you for the write up robert. It was a nice understandable read.

fwiw: I've given up (at least for now) on trying to build the library with FPC. It simply refuses to change the soname, which is one of the main parts of the issue. Can probably approached by using symlinks but the while idea was to make things easier and not complicate things (even) further.


can these be placed in the fpc.cfg file, so that the script or .exe is invoked for every project without needing to add it via the Lazarus IDE?
Sure, no problem.

you can simply add ...
Code: [Select]
-k--library-path="/path/where/your/fake/libdl/is/stored"
... to your fpc.cfg file

But 'every project' is a very strict (or broad, depending on your view) concept. I better explain that one  :)

People can use Lazarus to cross compile to other platforms. It is not very intuitive if that would introduce libfakedl especially not for those platforms it has no meaning (et all). Besides that, some (Linux) host's "do not suffer" from this particular issue because the OS (still) relies on using 'old' trusty libc.

So, making it optional in the fpc.cfg file by using a symbol would be much nicer, which could look something like:
Code: [Select]
#ifdef usefakelibdl
-k--library-path="/path/where/your/fake/libdl/is/stored"
#endif
which would then allow to compile with
Code: [Select]
  FPC -B -dusefakelibdl programname.pas
Or in Lazarus's terms, you can add a define to either your project settings or create special build mode that defines the symbol (by default). Depends a little on your preference.

To make it more generic (and explicit at the same time) it would perhaps even be better to add additional checks such as
Code: [Select]
#ifndef FPC_CROSSCOMPILING
#ifdef RELEASE
#ifdef LINUX
#ifdef CPUX64
#ifdef usefakelibdl
-k--library-path="/path/where/your/fake/libdls/are/stored/per/target/$FPCTARGET
#endif
#endif
#endif
#endif
#endif
but it depends a little for which exact situation(s) you want to make use of the fake libdl. I've gone overboard with the checks simply because I would opt using the fakelibdl only for this particular target (and only if you wan it to). Note a) the additional checks and b) the part where an extra directory ($FPCTARGET) is introduced which allows the fake dl library to be target dependent.

As an additional note to your post. Note that someone could opt (such as fpcUpDeluxe) for shipping the fake library so that user's do not have to compile it themselves and by using the custom path it can be stored somewhere neatly where it doesn't have to be a bother. Still risky since you would have to make darn sure the symbols declared in the fake library have to match otherwise it could lead to compiler (actually link) errors.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: DonAlfredo on July 05, 2023, 04:40:54 pm
About fpcupdeluxe.

As there are two methods to circumvent the GLIBC versioning, I am still investigating what to do.
Implemented at the moment is the easy one.
I have added a linux-legacy cross-compile target. This target will download very olds libs. And link against these. It also sets FPC_USE_LIBC to force the legacy-rtl to use libc calls instead of direct sys-calls. I am testing this.
Method2 with the fake library is hard to do, and also more a hack than using old libs. But it works. Still looking into this.

And thanks for the nice read about this subject !!
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Thaddy on July 05, 2023, 04:57:44 pm
Jus test for < 2.34
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 05, 2023, 07:43:23 pm
Jus test for < 2.34
Just to humor the idea. How do you suggest doing that when... let's say .. cross-compiling from x86_64 to arm ?

All possible solution mentions loading libc and use get_version_number (don't think adding an arm emulator would simplify things), or use the gnu compiler to detect the version using the libc sources (adding dependencies for gcc, gnu libc sources which also isn't considered very user friendly not to mention having to write some c-code).

So that leaves us pretty much empty handed (unless there is something that I overlooked). Yes, you could opt for doing so when compiling where host and target are the same architecture.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 06, 2023, 08:20:38 pm
Jus test for < 2.34
[...]
All possible solution mentions loading libc and use get_version_number
[...]

and therein lies the problem - you need to load libc in order to get the version number, but you need to know the version number before you load libc!

i have come up with a solution that can work around this, but it is very very ugly. you have a compressed binary of your application, and a difference file (also compressed) that allows patching the (once uncompressed) binary from 2.2.5 compatible to 2.34 compatible. these are both bundled up into a simple console application (with no libc dependencies) that unpacks the original into /tmp and decompresses it, then decides which version you need and if required applies the patch before running the binary from /tmp. it actually works pretty well, is transparent to the user, but requires quite a bit of work to put together.


also Fred vS has now got a patched version of FPC that can generate GLIBC_2.2.5 versioned binaries without need for fake libraries or any other tricks:
https://github.com/fredvs/freepascal-ootb (https://github.com/fredvs/freepascal-ootb)

it appears that there is something 'odd' in external that has thwarted efforts to simply specify the GLIBC version for symbols, i'm moving towards thinking it is a bug that creates an incompatibility with the way that GLIBC 2.34 and later structure the /lib/x86_64-linux-gnu directory. basically there is a libdl.so.2 placeholder library file in there, but FPC can not 'see' it. if renamed to libdl.so then all is well from the FPC perspective and introducing versioned symbols is easy.

looking at an old linux (Mint 19.3, GLIBC 2.27) it seems there may never have been a libdl.so file or symlink, which leaves me a little surprised that the linux related code in dl.pp ever worked as intended.

now one could just hack the /lib/x86_64-linux-gnu directory, but that is a rather impolite thing to do and may break things elsewhere in GLIBC.


cheers,
rob   :-)

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 06, 2023, 08:58:04 pm
and therein lies the problem - you need to load libc in order to get the version number, but you need to know the version number before you load libc!
Who would have thought chickens would produce eggs and vice verse  :D

Quote
i have come up with a solution that can work around this
tbh I haven't had the time to investigate further. In theory it should be possible to extract the information form the compiled lib but the main problem is figuring out how is it stored.

Quote
also Fred vS has now got a patched version of FPC that can generate GLIBC_2.2.5 versioned binaries without need for fake libraries or any other tricks:
Thank you for mentioning that. I had no idea fred was working on that. It should be possible to clean that up a little but note that I'm not that familiar with the compiler internals.

Quote
looking at an old linux (Mint 19.3, GLIBC 2.27) it seems there may never have been a libdl.so file or symlink, which leaves me a little surprised that the linux related code in dl.pp ever worked as intended.
Magic  :D

If you look a bit closer then you'll notice that the dl functions are part of glibc and as such the FPC unit links against libc (on/for certain targets) so that is probably what you have overlooked ?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 06, 2023, 09:19:33 pm
If you look a bit closer then you'll notice that the dl functions are part of glibc and as such the FPC unit links against libc (on/for certain targets) so that is probably what you have overlooked ?

i take it you mean the line in dl.pp that reads:
Code: Pascal  [Select][+][-]
  1. {$if defined(linux)}
  2.     { if libc is not linked explicitly, FPC might chose the wrong startup code, as
  3.       libdl depends on libc on linux, this does not hurt }
  4.     {$linklib c}
  5. {$endif}

i've found that the $linklib is ignored, no matter what i change it to.

similarly, changing the line:
Code: Pascal  [Select][+][-]
  1.     LibDL = 'dl';

makes no difference. the sting is ignored no matter what it contains.

it is as if the parameters passed to external should be directing the linker, but are instead ignored. hence the need to provide the linker with external cues - like the fake libdl.so file dropped into the project directory. i've found that even if the fake libdl.so file contains no symbols, it still works to allow versioned symbols introduced to pp.dl to be picked up correctly. remove the empty fake libdl.so file, and the binary won't run against GLIBC 2.27.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 06, 2023, 10:21:12 pm
@robert:
I am not quite sure what you are saying.

If you are looking for actual output of the linker then you explicitly should make use of the unit. f.e.
Code: Pascal  [Select][+][-]
  1. program test;
  2. uses
  3.   dl;
  4. begin
  5.   writeln('hello');
  6. end.
  7.  
And when you compile
Code: [Select]
fpc -va -B -k--trace -k--verbose -k--stats test.paswhen f.e. you have changed the name of the library....you are in for a (output log) treat  :)

More disturbing is the output from my current system in use:
Code: [Select]
/usr/bin/ld: mode elf_x86_64
attempt to open /home/apps/fpc/3.2.2/units/x86_64-linux/rtl/si_prc.o succeeded
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/si_prc.o
attempt to open /home/apps/fpc/3.2.2/units/x86_64-linux/rtl/abitag.o succeeded
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/abitag.o
attempt to open test.o succeeded
test.o
attempt to open /home/apps/fpc/3.2.2/units/x86_64-linux/rtl/system.o succeeded
/home/apps/fpc/3.2.2/units/x86_64-linux/rtl/system.o
attempt to open dl.o succeeded
dl.o
attempt to open ./libdl.so failed
attempt to open ./libdl.a failed
attempt to open /usr/lib/x86_64-linux-gnu//libdl.so failed
attempt to open /usr/lib/x86_64-linux-gnu//libdl.a succeeded
/usr/lib/x86_64-linux-gnu//libdl.a
/usr/bin/ld: dl.o: in function `DL_$$_UNIXGETMODULEBYADDR$POINTER$POINTER$OPENSTRING':
dl.pp:(.text.n_dl_$$_unixgetmodulebyaddr$pointer$pointer$openstring+0x4c): undefined reference to `dladdr'
/usr/bin/ld: link errors found, deleting executable `test'
[0.031] Executing "/usr/bin/ld" with command line "-b elf64-x86-64 -m elf_x86_64  --trace --verbose --stats --dynamic-linker=/lib64/ld-linux-x86-64.so.2     -L. -o test -T link12679.res -e _dynamic_start"
[0.047] test.pas(6,1) Error: Error while linking
[0.047] test.pas(6,1) Fatal: There were 1 errors compiling module, stopping
[0.047] Fatal: Compilation aborted
Error: /home/apps/fpc/3.2.2/bin/x86_64-linux/ppcx64 returned an error exitcode
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 06, 2023, 10:41:39 pm
just tried your short program and compiling line. it is indeed an impressive output.

so the compiler does not find libdl.so.2, but does find libdl.a instead. libdl.a being a short text file containing:
Code: Text  [Select][+][-]
  1. !<arch>

have just been discussing this with Fred vS. i was under the impression that when FPC encountered a shared library file called something like libdl.so.2 then it would use it, but that it could not distinguish between, for instance, libdl.so.2 and libdl.so.3. and also that when it finds libdl.so and libdl.so.2 then it would use libdl.so.

is my understanding of how external works wrong? is it that FPC simply can not see a library file that ends in .so.2 (or any other number)? i've had a hard time finding any useful documentation for external.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 06, 2023, 10:48:11 pm
is my understanding of how external works wrong? is it that FPC simply can not see a library file that ends in .so.2 (or any other number)? i've had a hard time finding any useful documentation for external.
Correct. To my knowledge FPC does not search for such an extension. Even stronger if you specify it in your header then the compiler simply ignores it (by overwriting the extension with .so). You can try it yourself now knowing how to generate some (meaningful) output  ;)   It depends on you installing the dev package which does that labour (of figuring out which specific library to use) for you.

fwiw: Fred (but probably others as well) addressed that in a more recent thread (sorry can't seem to find it). If there is no dev package you can solve it yourself with a symlink using the unversioned name that links to the versioned name of the library.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 06, 2023, 11:09:23 pm
It depends on you installing the dev package which does that labour (of figuring out which specific library to use) for you.

is this the dev package you mean?
Code: Text  [Select][+][-]
  1. user@DH61BE:~$ dpkg -s libc6-dev
  2. Package: libc6-dev
  3. Status: install ok installed
  4. Priority: optional
  5. Section: libdevel
  6. Installed-Size: 13037
  7. Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
  8. Architecture: amd64
  9. Multi-Arch: same
  10. Source: glibc
  11. Version: 2.35-0ubuntu3.1
  12. Provides: libc-dev

it comes pre-installed with the distros i am using - i didn't install it myself. but there is no libdl.so symlink in /lib/x86_64-linux-gnu:
Code: Text  [Select][+][-]
  1. user@DH61BE:~$
  2. user@DH61BE:~$ ls /lib/x86_64-linux-gnu/libdl*
  3. /lib/x86_64-linux-gnu/libdl.a  /lib/x86_64-linux-gnu/libdl.so.2
  4. user@DH61BE:~$

i get the same results from a fresh VM created from a Linux Mint 21.1 XFCE .iso. libc6-dev already installed, but no libdl.so symlink exists.

i shall sleep on this, it is now 9am here and i've been working away at this all night!


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 06, 2023, 11:17:17 pm
is this the dev package you mean?
I was speaking generally. Whenever you need to use a versioned library, say for example libgtk2, then you are required to install libgtk2-dev in order to actually be able to make use of it (sorry for the bad example but it was the first things that came to mind)..

The C library and it's brethren are a bit peculiar in that regards. Probably because things are so tight together, same as for libpthread (it was part of libc then it wasn't or the other way around, can't remember).

Quote
it comes pre-installed with the distros i am using - i didn't install it myself. but there is no libdl.so symlink in /lib/x86_64-linux-gnu:
Code: Text  [Select][+][-]
  1. user@DH61BE:~$
  2. user@DH61BE:~$ ls /lib/x86_64-linux-gnu/libdl*
  3. /lib/x86_64-linux-gnu/libdl.a  /lib/x86_64-linux-gnu/libdl.so.2
  4. user@DH61BE:~$
note the unversioned name libdl.a (analog for libdl.so in eyes of the linker/fpc) that symlinks to versioned name libdl.so.2

Quote
i shall sleep on this, it is now 9am here and i've been working away at this all night!
No problem. Thank you for the interesting discussion. Sleep well.

edit:
A very helpful read about versioning/symlinks/packaging/distributions: https://dmerej.info/blog/post/symlinks-and-so-files-on-linux/
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 07, 2023, 07:09:58 am
is this the dev package you mean?
In this particular case , yes.

For more information, see (also) libc release notes (https://sourceware.org/pipermail/libc-alpha/2021-August/129718.html):
Quote
In order to support smoother in-place-upgrades and to simplify
  the implementation of the runtime all functionality formerly
  implemented in the libraries libpthread, libdl, libutil, libanl has
  been integrated into libc.  New applications do not need to link with
  -lpthread, -ldl, -lutil, -lanl anymore.  For backwards compatibility,
  empty static archives libpthread.a, libdl.a, libutil.a, libanl.a are
  provided, so that the linker options keep working.  Applications which
  have been linked against glibc 2.33 or earlier continue to load the
  corresponding shared objects (which are now empty).  The integration
  of those libraries into libc means that additional symbols become
  available by default.  This can cause applications that contain weak
  references to take unexpected code paths that would only have been
  used in previous glibc versions when e.g. preloading libpthread.so.0,
  potentially exposing application bugs.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 07, 2023, 03:53:16 pm
A very helpful read about versioning/symlinks/packaging/distributions: https://dmerej.info/blog/post/symlinks-and-so-files-on-linux/ (https://dmerej.info/blog/post/symlinks-and-so-files-on-linux/)

excellent article - am not sure i understand it all yet, will have to read through it a few more times. what is most immediately useful is the -d parameter to readelf:
Code: Bash  [Select][+][-]
  1. user@Mint19:~/Desktop$ readelf -d -W test07 | grep "NEEDED"
  2.  0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
  3.  0x0000000000000001 (NEEDED)             Shared library: [libgdk-x11-2.0.so.0]
  4.  0x0000000000000001 (NEEDED)             Shared library: [libgtk-x11-2.0.so.0]
  5.  0x0000000000000001 (NEEDED)             Shared library: [libX11.so.6]
  6.  0x0000000000000001 (NEEDED)             Shared library: [libgdk_pixbuf-2.0.so.0]
  7.  0x0000000000000001 (NEEDED)             Shared library: [libgobject-2.0.so.0]
  8.  0x0000000000000001 (NEEDED)             Shared library: [libglib-2.0.so.0]
  9.  0x0000000000000001 (NEEDED)             Shared library: [libgthread-2.0.so.0]
  10.  0x0000000000000001 (NEEDED)             Shared library: [libgmodule-2.0.so.0]
  11.  0x0000000000000001 (NEEDED)             Shared library: [libpango-1.0.so.0]
  12.  0x0000000000000001 (NEEDED)             Shared library: [libcairo.so.2]
  13.  0x0000000000000001 (NEEDED)             Shared library: [libatk-1.0.so.0]
  14.  0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
  15. user@Mint19:~/Desktop$

this shows the shared libraries needed by the binary, and i can see binaries that work with pre 2.34 versions of GLIBC have libdl.so.2 listed as "NEEDED", while those that do not work do not have libdl.so.2 listed. this means i can build a test binary and instantly see if it is backward/forward compatible, and was one of the pieces of the puzzle that had up until now eluded me. it makes the job of testing out different solution so much quicker!

For more information, see (also) libc release notes (https://sourceware.org/pipermail/libc-alpha/2021-August/129718.html)

i had read that a couple of weeks back, but didn't understand the significance of libdl.a:
"For backwards compatibility, empty static archive [...] libdl.a [... is] provided, so that the linker options keep working. Applications
which have been linked against glibc 2.33 or earlier continue to load the corresponding shared objects (which are now empty).
"

so libdl.a is not a symlink, but some sort of a 'signpost' for the linker that indicates "nothing more to see here, move along to the next library".

it seems that some linux distros include a libdl.so symlink to libdl.so.2, while others do not. there is no hard-and-fast rule. Fred vS suggests that simply creating the symlink is safe and that it should not break anything - what do you think?

i'm currently think around the idea of creating a program or shell script that:
- patches the RTL sources to add @GLIBC_2.2.5 to all the externals that reference know GLIBC 2.2.5 compatible functions,
- runs the necessary commands to rebuild the RTL,
- creates the libdl.so symlink in /lib/x86_64-linux-gnu if it is not already present. or creates an empty libdl.so library in /lib/x86_64-linux-gnu if libdl.so.2 does not exist.

by my reckoning this should give a Lazarus/FPC that permanently generates binaries that are GLIBC 2.2.5 compatible - with @GLIBC_2.2.5 versioned libc symbols - and thus able to run against all versions of GLIBC up until such time as the GLIBC developers drop 2.2.5 support.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 08, 2023, 05:28:17 am

is this the dev package you mean?
Code: Text  [Select][+][-]
  1. Package: libc6-dev
  2.  
  3. it comes pre-installed with the distros i am using - i didn't install it myself. but there is no [b][tt]libdl.so[/tt][/b] symlink in [b][tt]/lib/x86_64-linux-gnu[/tt][/b]:
  4. [code=plain]user@DH61BE:~$
  5. user@DH61BE:~$ ls /lib/x86_64-linux-gnu/libdl*
  6. /lib/x86_64-linux-gnu/libdl.a  /lib/x86_64-linux-gnu/libdl.so.2
  7. user@DH61BE:~$

i get the same results from a fresh VM created from a Linux Mint 21.1 XFCE .iso. libc6-dev already installed, but no libdl.so symlink exists.

How Debian names libraries
https://www.debian.org/doc/debian-policy/ch-sharedlibs.html

Quote
The development package should contain a symlink for the associated shared library without a version number. For example, the libgdbm-dev package should include a symlink from /usr/lib/libgdbm.so to libgdbm.so.3.0.0. This symlink is needed by the linker (ld) when compiling packages, as it will only look for libgdbm.so when compiling dynamically.

Where are libdl.so and libdl.a located in Debian and Ubuntu?

Debian 7 Wheezy (2013)
https://packages.debian.org/search?suite=wheezy&arch=amd64&searchon=contents&keywords=libdl.so
https://packages.debian.org/search?suite=wheezy&arch=amd64&searchon=contents&keywords=libdl.a

Debian 11 Bullseye (2021):
https://packages.debian.org/search?suite=bullseye&arch=amd64&searchon=contents&keywords=libdl.so
https://packages.debian.org/search?suite=bullseye&arch=amd64&searchon=contents&keywords=libdl.a

Ubuntu 14.04 Trusty Tahr (2014)
https://packages.ubuntu.com/search?suite=trusty&arch=amd64&searchon=contents&keywords=libdl.so
https://packages.ubuntu.com/search?suite=trusty&arch=amd64&searchon=contents&keywords=libdl.a

Ubuntu 22.04 Jammy Jellyfish (2022) (libdl.so is not found in this version of Ubuntu)
https://packages.ubuntu.com/search?suite=jammy&arch=amd64&searchon=contents&keywords=libdl.so
https://packages.ubuntu.com/search?suite=jammy&arch=amd64&searchon=contents&keywords=libdl.a
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 08, 2023, 06:14:57 pm
If you wish to know more about those parameters (NEEDED etc) and about versioning then you could perhaps also have a look here (https://maskray.me/blog/2020-11-26-all-about-symbol-versioning) for more technical details.

so libdl.a is not a symlink, but some sort of a 'signpost' for the linker that indicates "nothing more to see here, move along to the next library".
Correct, though it could also be a symlink pointing to an 'empty' library.

Quote
Fred vS suggests that simply creating the symlink is safe and that it should not break anything - what do you think?
In all honestly: that I know just enough to be dangerous. In principle I think it can't harm but on the other side how does it reflect on functions that really requires a fix especially when code relies on certain behaviour.

Quote
i'm currently think around the idea of creating a program or shell script that:
- patches the RTL sources to add @GLIBC_2.2.5 to all the externals that reference know GLIBC 2.2.5 compatible functions,
My knowledge on linking is next to none but I still have the notion/idea that it should be possible to realize with a linker script that replaces the symbols. That would allow for a solution that is independent of any changes in the RTL/compiler.

I have tried to come up with an more intelligent answer on that subject but so far was unable to find something that was relevant enough to mention (hence my delayed reply). Trying to understand the gnu linker is probably a lifetime commitment  :)


@WayneSherman: thank you for the pointers/links !
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: funlw65 on July 09, 2023, 11:19:20 pm
I have a (Debian based) linux distro < 2.34, so I looked at the elf binary of my app
that gcc produces and mostly, functions are versioned at 2.2.5 but there are some
at 2.17, 2.27, 2.29 etc., I guess that is the lowest version that that respective function
was first introduced in glibc...

Can't try with a >= 2.34 to see the effect, and is OK for me to stay with my actual version
of linux, but, I'm pretty sure that if they had the courage to introduce
such restriction, the following one that will prevent older software to run on newer
glibc versions is around the corner. Probably a credible reason is already prepared.
And probably more will follow shortly after that, at a faster pace.

So, I understand why FreePascal is forced to follow suit without fighting back..

It might be a chance if the world opposes (musl might be the one?), as is the case of
init against systemd, but if the opposition does not win the popularity contest, then it is
just a matter of time to when the white flag will be raised. In a way, Linux follows Apple...
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 10, 2023, 06:13:24 am
If you wish to know more about those parameters (NEEDED etc) and about versioning then you could perhaps also have a look here (https://maskray.me/blog/2020-11-26-all-about-symbol-versioning) for more technical details.

a good read - but oh so complicated! it looks like --allow-shlib-undefined  passed to the linker may achieve the same result as a fake libdl.so file, has anyone tried this? i agree, it would be nice to find a solution that does not involve tinkering with the RTL source or creating fake libraries.


Quote
Fred vS suggests that simply creating the symlink is safe and that it should not break anything - what do you think?
[...] I think it can't harm but on the other side how does it reflect on functions that really requires a fix especially when code relies on certain behaviour.

that has always been one of my major concerns - and was pointed out by PascalDragon earlier on. however, as funlw65 alludes to, what happens if the old @GLIBC_2.2.5 symbols and the functions that lie behind them are depreciated by the GLIBC developers at some future time? these symbols are, after all, already 20 years old.

if some versioned symbols are depreciated, then strictly speaking i feel that libc.so.6 should be bumped up to libc.so.7, but we can not be certain this will happen in practice. Fred vS has emailed me with this concern. if the FPC RTL (and Lazarus LCL) made use of the C header files to define the prototypes of the library functions they use (such as dlopen() etc) then one could simply rebuild the RTL and LCL. but (in the case of the FPC RTL at least) the C header files are not used, instead the function prototypes hard-coded. and hard-coded in a selection of locations that it is not necessarily easy to locate - this is good reason in itself for ALL externals to library functions being brought together into a single .inc file. but that is way beyond the scope of my own experiments.

i would also suggest that research be carried out into having ONLY __libc_start_main, dlopen, and dlsym accessed by external. ALL other library calls should then be managed through dlopen and dlsym. if this is possible, then it substantially reduced the exposed surface, as well as allowing for the RTL et al to catch incompatibility errors and intelligently decide how to handle versioned symbols with multiple prototypes as required.


@WayneSherman: thank you for the pointers/links !

likewise, many thanks Wayne. we do need fresh eyes looking at these problems. it is a shame we do not have one or two of the GLIBC developers involved, as i am sure they could provide useful guidance! your checks indeed show how libdl.so symlink has itself been purged from some distros.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 10, 2023, 07:10:43 pm
from:  https://stackoverflow.com/questions/13753528/what-are-the-3-digits-in-a-so-name

Quote
Basically, the naming convention allows for three levels of compatibility for programs that link against the library. A program can choose to link against the library name itself, a specific major number, or a specific major.minor number. This is really up to an application developer to determine what makes the most sense.

from:  https://www.unix.com/unix-for-advanced-and-expert-users/90028-naming-conventions-shared-libraries-linux.html

Quote
They are version numbers, and are there for two reasons; so that you can safely and easily upgrade your libraries, and so you can have more than one version of them installed at the same time.

When there's two numbers there's a major and a minor version. libncursesw.so.5.6 has major version 5 and minor version 6; in theory any minor version of the same major version is compatible without recompiling, so programs that linked to libncursesw.so.5 wouldn't miss a beat if you upgraded to 5.7 for a bugfix. If you had an ancient program demanding version 4, you could safely install a 4.x library alongside the 5.x ones, and nothing but that program would use it.

Sometimes programmers don't think that far ahead though; they might link to a too specific version, breaking their program every time you upgrade a library, or link to libncursesw.so itself, causing crashes and/or strange runtime errors when the library's not what they expected.

A nice discussion on shared library versioning is here:
https://dcreager.net/2017/10/shared-library-versions/
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 10, 2023, 07:30:59 pm
Regarding Linux software source code that depends on an external library (some_library.so).  During development, it is compiled, linked, and tested against a specific library version (e.g. some_library.so.2.1) and possibly versioned symbols within that library (e.g. (GLIBC_2.2.5) dlopen).  (EDIT - What follows is in regard to *static* loading of a library or symbol with the use of the "external" compiler directive. Runtime binding i.e. dynamic loading of a library can have different rules since runtime version checking can be used)

Not knowing any better :-) and for the sake of conversation, here are some assertions (which may or may not be correct):

Versioned Libraries
1) A *versioned* reference to an external library should be embedded in the executable. Why?  Because it was designed and tested with a version that is known to work correctly.  The referenced version should usually refer to the *major* version of the library only (e.g. some_library.so.2).

2) If a minor version of a shared library is specifically required for correct program execution, then the referenced version in the ELF file should include the minor version (e.g. some_library.so.2.1). EDIT - I feel like this is not a good idea.

3) When some_library.so.2 has backward incompatible changes (API, ABI, or changed function behaviors), the library developers *should* increment the library major version. (e.g. some_library.so.3)

Versioned Symbols within a Library
4) If versioned symbols are available (e.g. glibc), then *versioned* symbols for the external library should be embedded in the executable (e.g. (GLIBC_2.2.5) dlopen).  For the same reason as #1, because the source code using the symbol was designed and tested with a version that is known to work correctly.

5) For versioned symbols, when a function has backward incompatible changes (API, ABI, or behavior) the library developers *should* increment the symbol version.  EDIT - The previous version of that symbol should still be available to maintain backward compatibility.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: circular on July 12, 2023, 07:15:07 am
About specifying the minor version number, in general that may not be a good idea but unfortunately I have an example of a library (libavif) that has introducted breaking changes at many points, including minor version numbers.

In LazPaint, that runs as well on MacOS and Windows where I cannot know which version of the library would be available, the only solution I found was to bind without version but to check the version at runtime, and to use the version of the records that corresponds to it.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 12, 2023, 05:58:15 pm
About specifying the minor version number, in general that may not be a good idea but unfortunately I have an example of a library (libavif) that has introducted breaking changes at many points, including minor version numbers.

In LazPaint, that runs as well on MacOS and Windows where I cannot know which version of the library would be available, the only solution I found was to bind without version but to check the version at runtime, and to use the version of the records that corresponds to it.

If relying on a specific minor version, does that make distributing your application on Linux difficult?  You might have to statically link or include the library with your application if the minor version required is not available from the distro repository.  But then you have to keep the app or library patched for security issues instead of relying on the distro to do that.

For the "libavif" library, you might not even have the major version available that you need.  For example:

Debian 10 Buster (2019):
libavif is not included in the repos

Debian 11 Bullseye (2021):
https://packages.debian.org/search?suite=bullseye&section=all&arch=amd64&searchon=names&keywords=libavif
https://packages.debian.org/bullseye/amd64/libavif9/filelist
libavif9 with files libavif.so.9 and libavif.so.9.0.0

bullseye-backports
https://packages.debian.org/bullseye-backports/amd64/libavif13/filelist
libavif13 with files libavif.so.13 and libavif.so.13.0.0

Debian 12 Bookworm (2023):
https://packages.debian.org/search?suite=bookworm&arch=amd64&searchon=names&keywords=libavif
https://packages.debian.org/bookworm/amd64/libavif15/filelist
libavif15 with files libavif.so.15 and libavif.so.15.0.1

In the future, lets say bullseye updates libavif9 with a security release and increments to libavif.so.9.1.0 or libavif.so.9.0.1.  At that point they probably will remove libavif.so.9.0.0 from the repo.

EDIT - Dynamically loading and runtime checking a library version allows for more flexibility.  I added to my previous post (two posts up):  "(EDIT - What follows is in regard to *static* loading of a library or symbol with the use of the "external" compiler directive. Runtime binding i.e. dynamic loading of a library can have different rules since runtime version checking can be used)"
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: circular on July 12, 2023, 10:47:14 pm
For now, the following versions are handled by BGRABitmap:
Code: Pascal  [Select][+][-]
  1. const
  2.   AVIF_VERSION_0_8_4 = 00080400;
  3.   AVIF_VERSION_0_9_2 = 00090200;
  4.   AVIF_VERSION_0_9_3 = 00090300;
  5.   AVIF_VERSION_0_10_0 = 00100000;
  6.   AVIF_VERSION_0_10_1 = 00100100;
  7.   AVIF_VERSION_0_11_0 = 00110000;
  8.  
It handles up to 0.11.0 and from version 0.11.1 it is not compatible anymore (an exception is raised by safety checks). So I will need to update BGRABitmap and LazPaint to handle newer versions. And hope records will not change again in the future.

I don't know if libavif provide a table of versions, but that would be great to use some compatible functions of latest version handled (0.11.0 in this case). I don't know if this can be done with dynamic linking.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 15, 2023, 05:04:19 pm
another useful data point:

Code: Bash  [Select][+][-]
  1. user@DH61BE:~$ readelf --dyn-syms -W /lib/x86_64-linux-gnu/libc.so.6 | grep -E " dl|start_main|Num:" | (sed -u 1q; sort -k 8)
  2.    Num:    Value          Size Type    Bind   Vis      Ndx Name
  3.    977: 000000000008fe60    74 FUNC    GLOBAL DEFAULT   15 dladdr1@GLIBC_2.3.3
  4.    978: 000000000008fe60    74 FUNC    GLOBAL DEFAULT   15 dladdr1@@GLIBC_2.34
  5.    139: 000000000008fe30    42 FUNC    GLOBAL DEFAULT   15 dladdr@GLIBC_2.2.5
  6.    138: 000000000008fe30    42 FUNC    GLOBAL DEFAULT   15 dladdr@@GLIBC_2.34
  7.   1998: 000000000008feb0    69 FUNC    GLOBAL DEFAULT   15 dlclose@GLIBC_2.2.5
  8.   2000: 000000000008feb0    69 FUNC    GLOBAL DEFAULT   15 dlclose@@GLIBC_2.34
  9.    163: 000000000008ff00   536 FUNC    GLOBAL DEFAULT   15 dlerror@GLIBC_2.2.5
  10.    162: 000000000008ff00   536 FUNC    GLOBAL DEFAULT   15 dlerror@@GLIBC_2.34
  11.   2348: 0000000000090430   134 FUNC    GLOBAL DEFAULT   15 dlinfo@GLIBC_2.3.3
  12.   2346: 0000000000090430   134 FUNC    GLOBAL DEFAULT   15 dlinfo@@GLIBC_2.34
  13.   1138: 0000000000174d30   532 FUNC    WEAK   DEFAULT   15 dl_iterate_phdr@@GLIBC_2.2.5
  14.    802: 00000000000905c0   155 FUNC    GLOBAL DEFAULT   15 dlmopen@@GLIBC_2.34
  15.    801: 00000000000905c0   155 FUNC    GLOBAL DEFAULT   15 dlmopen@GLIBC_2.3.4
  16.   1887: 0000000000090700   154 FUNC    GLOBAL DEFAULT   15 dlopen@GLIBC_2.2.5
  17.   1890: 0000000000090700   154 FUNC    GLOBAL DEFAULT   15 dlopen@@GLIBC_2.34
  18.    795: 00000000000907c0   206 FUNC    GLOBAL DEFAULT   15 dlsym@GLIBC_2.2.5
  19.    793: 00000000000907c0   206 FUNC    GLOBAL DEFAULT   15 dlsym@@GLIBC_2.34
  20.   1125: 00000000000908c0   219 FUNC    GLOBAL DEFAULT   15 dlvsym@GLIBC_2.2.5
  21.   1129: 00000000000908c0   219 FUNC    GLOBAL DEFAULT   15 dlvsym@@GLIBC_2.34
  22.    678: 0000000000029dc0   328 FUNC    GLOBAL DEFAULT   15 __libc_start_main@GLIBC_2.2.5
  23.    674: 0000000000029dc0   328 FUNC    GLOBAL DEFAULT   15 __libc_start_main@@GLIBC_2.34
  24. user@DH61BE:~$
  25. user@DH61BE:~$


if i'm not mistaken, the above tells us that the @GLIBC_2.2.5 and @GLIBC_2.34 versions of each of main libc/libdl functions used in FPC's RTL in fact map onto the same code. ie: __libc_start_main@GLIBC_2.2.5 and __libc_start_main@@GLIBC_2.34 both point to the same (0x29dc0) entry point, dlopen@GLIBC_2.2.5 and dlopen@GLIBC_2.34 both point to the same (0x90700) entry point, etc.

this would negate any arguments about wanting to use the 'most recent' version of a given function as it will have bugs fixed that may remain existing in an older version; the old (2.2.5) and new (2.34) versions are one and the same. quoting from another thread:

as long as the version number used exists (which we have just checked using readelf) the linker should (as far as i can see, although i am far from an expert) be happy. we end up with a binary file that will run against an early version of glibc without needing to build on an 'old' VM. would this work?

And what if the user does not want the old behavior? What if the new function fixed some critical functionality and by using the old one you'll run into problems because code you expect to work against the new behavior will run into problems? The __libc_start_main is exactly such an example.
(my bold italics)

if i am not mistaken - and i would be happy for anyone to demonstrate so - PascalDragon is wrong.

now i have only checked a few of the symbols from GLIBC, someone else may wish to conduct a more exhaustive check. perhaps write something to pick out all the matching sets of functions and for each set check for 'value' fields that are not the same.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 15, 2023, 05:49:02 pm
Code: Bash  [Select][+][-]
  1. user@DH61BE:~$ readelf --dyn-syms -W /lib/x86_64-linux-gnu/libc.so.6 | grep -E " dl|start_main|Num:" | (sed -u 1q; sort -k 8)
  2.    Num:    Value          Size Type    Bind   Vis      Ndx Name
  3.    977: 000000000008fe60    74 FUNC    GLOBAL DEFAULT   15 dladdr1@GLIBC_2.3.3
  4.    978: 000000000008fe60    74 FUNC    GLOBAL DEFAULT   15 dladdr1@@GLIBC_2.34
  5.    139: 000000000008fe30    42 FUNC    GLOBAL DEFAULT   15 dladdr@GLIBC_2.2.5
  6.    138: 000000000008fe30    42 FUNC    GLOBAL DEFAULT   15 dladdr@@GLIBC_2.34
  7. ...

now i have only checked a few of the symbols from GLIBC, someone else may wish to conduct a more exhaustive check. perhaps write something to pick out all the matching sets of functions and for each set check for 'value' fields that are not the same.

Although those symbols map to the same function code, there are symbols that map to different implementations as seen in this article:

https://developers.redhat.com/blog/2019/08/01/how-the-gnu-c-library-handles-backward-compatibility

Quote
For example, if we look at the 32-bit libc-2.29.so's dynamic symbol table, we see three versions of the glob64 function (in 2017, the glob function was changed to handle dangling symlinks differently, which would cause older programs to crash, but that's a different story):

Code: [Select]
$ readelf --dyn-syms -W /lib/libc-2.29.so | grep glob64
   411: 0012d0e0  7183 FUNC    GLOBAL DEFAULT   14 glob64@GLIBC_2.1
   412: 0012edb0  7183 FUNC    GLOBAL DEFAULT   14 glob64@GLIBC_2.2
   413: 000b69a0  7183 FUNC    GLOBAL DEFAULT   14 glob64@@GLIBC_2.27

BTW, one of my search results found an appropriate description which struck me as hilarious:
  "Versioned Symbols - A New Level of Hell" :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 15, 2023, 06:11:13 pm
as long as the version number used exists (which we have just checked using readelf) the linker should (as far as i can see, although i am far from an expert) be happy. we end up with a binary file that will run against an early version of glibc without needing to build on an 'old' VM. would this work?

And what if the user does not want the old behavior? What if the new function fixed some critical functionality and by using the old one you'll run into problems because code you expect to work against the new behavior will run into problems? The __libc_start_main is exactly such an example.

Taking the example of the glob64 function:

Quote
...if we look at the 32-bit libc-2.29.so's dynamic symbol table, we see three versions of the glob64 function (in 2017, the glob function was changed to handle dangling symlinks differently, which would cause older programs to crash, but that's a different story):

Code: [Select]
$ readelf --dyn-syms -W /lib/libc-2.29.so | grep glob64
   411: 0012d0e0  7183 FUNC    GLOBAL DEFAULT   14 glob64@GLIBC_2.1
   412: 0012edb0  7183 FUNC    GLOBAL DEFAULT   14 glob64@GLIBC_2.2
   413: 000b69a0  7183 FUNC    GLOBAL DEFAULT   14 glob64@@GLIBC_2.27

If a security issue is found in glob64, I assert a future release of libc will fix ALL of the implementations.  For other types of bugs fixed in the same function I assert that ALL implementations should get those fixes, unless fixing that bug changes the behavior in a way that breaks too much existing code (and it is not a security issue).  If this is true, then linking to a specific (older) version of a function (which was used to design and test the FPC code) is the correct thing to do.



Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 15, 2023, 07:37:06 pm
checking for matching base name but different entry points reveals:
Code: Bash  [Select][+][-]
  1. user@DH61BE:~$ readelf --dyn-syms -W /lib/x86_64-linux-gnu/libc.so.6 | (sed -u 1q; LC_COLLATE=C sort -k8) | ./project3
  2. _sys_nerr                     GLIBC_2.12     GLIBC_2.2.5    GLIBC_2.3      GLIBC_2.4      
  3. fmemopen                      GLIBC_2.22     GLIBC_2.2.5    
  4. glob64                        GLIBC_2.27     GLIBC_2.2.5    
  5. glob                          GLIBC_2.27     GLIBC_2.2.5    
  6. lio_listio64                  GLIBC_2.34     GLIBC_2.2.5    GLIBC_2.4      
  7. lio_listio                    GLIBC_2.34     GLIBC_2.2.5    GLIBC_2.4      
  8. memcpy                        GLIBC_2.14     GLIBC_2.2.5    
  9. nftw64                        GLIBC_2.3.3    GLIBC_2.2.5    
  10. nftw                          GLIBC_2.3.3    GLIBC_2.2.5    
  11. posix_spawn                   GLIBC_2.15     GLIBC_2.2.5    
  12. posix_spawnp                  GLIBC_2.15     GLIBC_2.2.5    
  13. pthread_attr_getaffinity_np   GLIBC_2.34     GLIBC_2.3.3    GLIBC_2.3.4    
  14. pthread_attr_setaffinity_np   GLIBC_2.32     GLIBC_2.3.3    GLIBC_2.3.4    
  15. pthread_cond_broadcast        GLIBC_2.3.2    GLIBC_2.2.5    
  16. pthread_cond_destroy          GLIBC_2.3.2    GLIBC_2.2.5    
  17. pthread_cond_init             GLIBC_2.3.2    GLIBC_2.2.5    
  18. pthread_cond_signal           GLIBC_2.3.2    GLIBC_2.2.5    
  19. pthread_cond_timedwait        GLIBC_2.3.2    GLIBC_2.2.5    
  20. pthread_cond_wait             GLIBC_2.3.2    GLIBC_2.2.5    
  21. pthread_getaffinity_np        GLIBC_2.32     GLIBC_2.3.3    GLIBC_2.3.4    
  22. pthread_kill                  GLIBC_2.34     GLIBC_2.2.5    
  23. pthread_setaffinity_np        GLIBC_2.34     GLIBC_2.3.3    GLIBC_2.3.4    
  24. quick_exit                    GLIBC_2.24     GLIBC_2.10    
  25. realpath                      GLIBC_2.3      GLIBC_2.2.5    
  26. regexec                       GLIBC_2.3.4    GLIBC_2.2.5    
  27. sched_getaffinity             GLIBC_2.3.4    GLIBC_2.3.3    
  28. sched_setaffinity             GLIBC_2.3.4    GLIBC_2.3.3    
  29. sys_nerr                      GLIBC_2.12     GLIBC_2.2.5    GLIBC_2.3      GLIBC_2.4      
  30. timer_create                  GLIBC_2.34     GLIBC_2.2.5    GLIBC_2.3.3    
  31. timer_delete                  GLIBC_2.34     GLIBC_2.2.5    GLIBC_2.3.3    
  32. timer_getoverrun              GLIBC_2.34     GLIBC_2.2.5    GLIBC_2.3.3    
  33. timer_gettime                 GLIBC_2.34     GLIBC_2.2.5    GLIBC_2.3.3    
  34. timer_settime                 GLIBC_2.34     GLIBC_2.2.5    GLIBC_2.3.3    
  35. user@DH61BE:~$
  36. user@DH61BE:~$

using the following pascal program to do the filtering:
Code: Pascal  [Select][+][-]
  1. program project3;
  2.  
  3. Uses sysutils, strutils;
  4.  
  5. var A0, A1, N0, N1, V1, Si, So:string;
  6.                             go:boolean;
  7.                           I, J:integer;
  8.  
  9. begin
  10.   A0:='';                                              // address, previous iteration
  11.   N0:='';                                              // name, previous iteration
  12.   So:='';                                              // output line buffer
  13.   go:=false;
  14.   while not eof do
  15.   begin
  16.     readln(Si);
  17.  
  18.     I:=pos(': 0', Si);                                 // locate start of 'value' field (address)
  19.     if I<>0 then
  20.     begin
  21.       delete(Si, 1, I+1);
  22.       A1:=leftstr(Si, 16);                             // extract address, 16 hex digits (64-bit)
  23.  
  24.       Si:=trim(Si);                                   // trim off any leading or trailing spaces
  25.       if (rightstr(Si, 1)=')') and (pos(' (', Si)<>0)  then            // check for any trailing ' (nn)'
  26.       begin
  27.         while rightstr(Si, 1)<>' ' do delete(Si, length(Si), 1);       // trim back to a trailing space
  28.         Si:=trim(Si)                                                   // trim off trailing space(s)
  29.       end;
  30.  
  31.       while pos(' ', Si)<>0 do delete(Si, 1, 1);       // delete everything up to 'name' field
  32.  
  33.       I:=pos('@', Si);                                 // locate beginning of versioning (at end of name)
  34.       if I<>0 then
  35.       begin
  36.         N1:=leftstr(Si, I-1);                          // extract unversioned name
  37.         while pos('@', Si)<>0 do delete(Si, 1, 1);     // delete everything up to version (including @ or @@)
  38.         V1:=Si;                                        // and extract version
  39.  
  40.         if N1<>N0 then begin                           // name mismatch -> finish off previous line(s)
  41.                         if go then writeln(So);        // only write out if there is an address mismatch
  42.                         go:=false;
  43.                         So:=''                         // clear output buffer
  44.                       end
  45.                  else if A1<>A0 then go:=true;         // name match + address mismatch -> allow output
  46.  
  47.         if So='' then So:=padright(N1, 30) + padright(V1, 15)          // <name> <1st ver>
  48.                  else So:=So + padright(V1, 15);                       // append <nth ver>
  49.  
  50.         A0:=A1;
  51.         N0:=N1
  52.       end
  53.     end
  54.   end;
  55.   if go then writeln(So)                               // if address mismatch output the pending last line
  56. end.

the question is, how much do we care about these particular libc functions? are any of them used anywhere by the Lazarus LCL? or by programmers in general?


BTW, one of my search results found an appropriate description which struck me as hilarious:
  "Versioned Symbols - A New Level of Hell" :-)

in the windows community it is called "DLL Hell":
https://en.wikipedia.org/wiki/DLL_Hell (https://en.wikipedia.org/wiki/DLL_Hell)


cheers,
rob   :-)


addendum: needed LC_COLLATE=C so that sort didn't do stupid things with underscore characters. this brings in sys_nerr and _sys_nerr. also updated the pascal filter program (project2 -> project3) to ensure no version numbers were missing from an output line.
addendum 11-aug-2023: added lines to trim any trailing '(nn)' after the version number. in practice, didn't change output.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 16, 2023, 01:13:36 am
checking for matching base name but different entry points reveals:
Code: Bash  [Select][+][-]
  1. user@DH61BE:~$ readelf --dyn-syms -W /lib/x86_64-linux-gnu/libc.so.6 | (sed -u 1q; sort -k8) | ./project2
  2.  
  3. fmemopen                      GLIBC_2.22     GLIBC_2.2.5    
  4. glob64                        GLIBC_2.2.5    GLIBC_2.27    
  5. glob                          GLIBC_2.2.5    GLIBC_2.27    
  6. ...

In addition, this shows glibc API and ABI changes and backward compatibility across versions:
https://abi-laboratory.pro/?view=timeline&l=glibc
(the open source tools to generate these reports are linked at the bottom of the page)

See also:  https://sourceware.org/glibc/wiki/Testing/ABI_checker

Breaking changes are shown in the Binary Compatibility reports:
https://abi-laboratory.pro/index.php?view=compat_report&l=glibc&v1=2.35&v2=2.37&obj=7dee8&kind=abi

One example from that page for poll.h, libc.so.6
[−] ppoll ( struct pollfd* fds, nfds_t nfds, struct timespec const* timeout, sigset_t const* sigmask ) @@ GLIBC_2.4
Change:
The parameter sigmask became passed in rbp register instead of r10.
Effect:
Applications will read the wrong memory block instead of the parameter value.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: TRon on July 16, 2023, 02:20:06 am
In addition, this shows glibc API and ABI changes and backward compatibility across versions:
https://abi-laboratory.pro/?view=timeline&l=glibc
(the open source tools to generate these reports are linked at the bottom of the page)
Thank you for that very informative link (I was not aware such thing even existed).
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 20, 2023, 10:57:31 pm
The versioned symbols issue is not unique to FPC / Lazarus:

Rust:
https://github.com/rust-lang/libc/issues/1412
https://kobzol.github.io/rust/ci/2021/05/07/building-rust-binaries-in-ci-that-work-with-older-glibc.html

Go Lang:
https://utcc.utoronto.ca/~cks/space/blog/programming/GoAndGlibcVersioning

Cython/Python:
https://snorfalorpagus.net/blog/2016/07/17/compiling-python-extensions-for-old-glibc-versions/
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 20, 2023, 11:05:16 pm
I think glibc or parts of it should be depended on as little as possible which will result in fewer issues and be easier to maintain.

If most agree that the final executable (elf) should have *versioned* symbols, then how they get there is the main question.

Should the symbol versions be specified the the fpc source code or should the linker create the versioned symbols based on the libraries present on the system at compile time?

Related questions:
Are the fpc glibc header translations kept up-to-date with glibc API changes?
Is the fpc runtime itself a user the glibc api?
Does fpc expose any parts of the glibc api for general use by other developers?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 21, 2023, 02:38:02 pm
If most agree that the final executable (elf) should have *versioned* symbols, then how they get there is the main question. Should the symbol versions be specified the the fpc source code or should the linker create the versioned symbols based on the libraries present on the system at compile time?
Are the fpc glibc header translations kept up-to-date with glibc API changes?
Is the fpc runtime itself a user the glibc api?
Does fpc expose any parts of the glibc api for general use by other developers?

for programs that use threading or the LCL, glibc functions are used. for a simple 'console application' (non-GUI) without threading, the glibc functions are NOT used. the glibc functions may also be freely used by the programmer, but that is the programmer's problem to deal with. currently the latest version of each glibc symbol is linked to, but the code within the FPC RTL and Lazarus LCL is old - in the case of the RTL dating back to 2005. this is a major problem and will eventually result in FPC/Lazarus no longer being able to generate working linux x86-64 binaries.

i have been in touch with the glibc developers, and the feedback i received is that:
the FPC RTL should be explicitly specifying glibc symbol versions, and the symbol versions used should be the "base" ones which are relatively easy to extract from libc.so.6 in an automated fashion. the "base" symbols do not change over time, and will be maintained essentially for the life of the x86-64 instruction set. these 'base symbols' will pair with the current RTL pascal source without needing to change any code (beyond actually specifying the versioned symbols). these versioned symbols will needed to be extracted once for each architecture from a libc.so.6, and then incorporated in the RTL source. for x86-64 most will likely be @GLIBC_2.2.5

for example dlopen should be implemented thus:
function dlopen(Name : PChar; Flags : longint) : Pointer; cdecl; external libdl name 'dlopen@GLIBC_2.2.5';


the full discussion with the libc developers is available here:
https://sourceware.org/pipermail/libc-alpha/2023-July/thread.html#150163 (https://sourceware.org/pipermail/libc-alpha/2023-July/thread.html#150163)

attached below is a .pdf of the (at the moment) 13 email messages with replies highlighted.


cheers,
rob   :-)

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Handoko on July 21, 2023, 04:10:30 pm
Hello all. I did not follow the discussion but hope it can be useful for others.

I ever had libc issue with my Lazarus but that only happened when I installed latest version of Lazarus on a several years old Ubuntu. I solved the problem by using manual build Lazarus.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: MvC on July 22, 2023, 11:15:52 am
Hello,

I've been notified of this discussion by private mail.

That the libc unit would need to use versioning on linux to cater for the correct struct  layouts, is clear.

But can someone please *exactly* explain in a private mail to michael@freepascal.org why dlopen() would need to be versioned ?

From all messages here (and a lot of private messages) I still do not have a clear picture why dlopen would need to be versioned.
Sure, it could be done easily enough, but even the mails to Florian Weimer do not properly explain the why.
Exactly what problem would that solve ?

Please include a simple console application that can be used to demonstrate the problem.

In order to solve a problem, you need first to exactly identify the problem.
From all the messages here, I still get no clear picture of what exactly you're trying to solve.

Michael.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 23, 2023, 08:22:02 am
[...] can someone please *exactly* explain [...] why [a symbol] would need to be versioned ?
[...] In order to solve a problem, you need first to exactly identify the problem.

email sent. in summary, consider memcpy()
https://man7.org/linux/man-pages/man3/memcpy.3.html (https://man7.org/linux/man-pages/man3/memcpy.3.html)

       Failure to observe the requirement that the memory areas do not
       overlap has been the source of significant bugs.  (POSIX and the
       C standards are explicit that employing memcpy() with overlapping
       areas produces undefined behavior.)  Most notably, in glibc 2.13
       a performance optimization of memcpy() on some platforms
       (including x86-64) included changing the order in which bytes
       were copied from src to dest.

       This change revealed breakages in a number of applications that
       performed copying with overlapping areas.  Under the previous
       implementation, the order in which the bytes were copied had
       fortuitously hidden the bug, which was revealed when the copying
       order was reversed.  In glibc 2.14, a versioned symbol was added
       so that old binaries (i.e., those linked against glibc versions
       earlier than 2.14) employed a memcpy() implementation that safely
       handles the overlapping buffers case (by providing an "older"
       memcpy() implementation that was aliased to memmove(3)).


with FPC, if memcpy() is not explicitly versioned in the Pascal source, then the version of the memcpy() symbol present in the resulting ELF binary will vary depending on the installed glibc at compile-time. this version decision is made by the compile-time linker: either memcpy@GLIBC_2.2.5 or memcpy@GLIBC_2.14. the linker always selects for the 'newest' version found at compile-time if not directed otherwise.

the resulting binary will behave differently depending on the version of memcpy() selected by the compile-time linker.


the same principal applies to __libc_start_main. changes are 'in the air', and there is suggestion that at some not-too-distant future time the parameters to __libc_start_main may be changed. this will result in a new versioned __libc_start_main being introduced, which FPC will link against unless directed otherwise. this will result in an ELF binary that crashes if created on a machine that has this new version of __libc_start_main available. simple as that.

the same principal as applies to __libc_start_main then applies to dlopen() or any other glibc symbol.

to avoid this Florian Weimer has confirmed that FPC should link against the BASE version of the glibc symbols. essentially, this is the @GLIBC_2.2.5 versions - getting the right version numbers involves some one-off processing of the output from readelf -a libc.so.6.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: abouchez on July 25, 2023, 09:41:21 am
Some related discussion and code at https://github.com/synopse/mORMot2/issues/211

Even if my program uses the proper symbol names, we are still forced to compile with an old libc.
We really need some RTL changes at low level, e.g. to resollve the `__libc_start_main@@GLIBC_2.34` hardcoded symbol issue.

In the meanwhile, the only solution seems to compile on an old Linux distribution.
What I sometimes do, if I don't want to use another distribution, is to run the Windows-to-Linux fpcupdeluxe cross-compilers using Wine.  8-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on July 25, 2023, 09:50:28 am
Keep in mind that in general we only use syscall wrapping functions from libc, not the language utilities.   There are usually simple wrappers.

So no memcpy or glob but own move() and opendir/readdir/closedir implementations on top of getdirectoryentries.

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: abouchez on July 25, 2023, 11:27:19 am
Keep in mind that in general we only use syscall wrapping functions from libc, not the language utilities.
You are right:  most of the OS APIs are using direct syscall in the FPC RTL.
But this is not true for the `__libc_start_main` link in system.pp nor libdl nor cthreads units, IIRC.
And a single broken name link is enough to avoid proper execution.

Also note that calling syscall is not a good idea, e.g. when there are some VDSO wrappers available.
clockgettime syscall is 20 times slower with a syscal than the one from libc... and this function could be very often call, e.g. if you measure execution time with accuracy, which is a very common task.
See https://synopse.info/forum/viewtopic.php?pid=31342#p31342
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on July 25, 2023, 12:15:37 pm
Quote
Also note that calling syscall is not a good idea, e.g. when there are some VDSO wrappers available.
clockgettime syscall is 20 times slower with a syscal than the one from libc... and this function could be very often call, e.g. if you measure execution time with accuracy, which is a very common task.
See https://synopse.info/forum/viewtopic.php?pid=31342#p31342

That a libc call could do more than just syscall  was already known 19 years ago, which is why I crafted the -dFPC_USE_LIBC option back then. (actually originally for FreeBSD, but quickly ported to Linux) for people that encounter such issues. The question is if it should be the default or not, and what that means for the longevity of a release.  IMHO distribution specific packages (.deb .rpm) should have changed long ago, since they are not multi distro packages to begin with.

The value of syscall for bootstrapping using a single binary release was a known factor however, and we were all reluctant to desert it.  Partially because there was so much going on with libc all the time. In this era of LTS releases that has quieted down somewhat, but keep in mind that every breakage of a release tar (still the official Linux distribution of FPC) is one too many.

Personally, I gave up on Linux for anything but local work (so no distributing binaries as per Windows model)

All the things in this thread have come up multiple times over the years, but the point is that nobody really tried to create a multi distribution binary based on it, maintain it for a while and prove that the concept really works rather than just echoing factoids and well meant intentions rather than real experiences.

Specially in this GIT era, it would be so easy to have a branch shadowing trunk or fixes for that.

Keep in mind that in general we only use syscall wrapping functions from libc, not the language utilities.
You are right:  most of the OS APIs are using direct syscall in the FPC RTL.
But this is not true for the `__libc_start_main` link in system.pp nor libdl nor cthreads units, IIRC.
And a single broken name link is enough to avoid proper execution.

Yeah, but they are not used in the compiler. I would at least retain syscall builds for the bootstrap compilers of every release.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: DonAlfredo on July 25, 2023, 01:10:30 pm
I am willing to help, if versioned linking might/will be accepted by FPC devs.
I have already made a FPC source scanner to find all libc-calls based on this header file.
Based on headers from: https://github.com/wheybags/glibc_version_header/blob/master/version_headers/x64/force_link_glibc_2.27.h

Proposal.
All libc-calls (the externals) might be defined from an include file that has a versioned and an unversioned definition of every call. Would also cleanup the FPC sources a bit. As stated previously, care must be taken to include all libc CPU-OS combo's.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on July 25, 2023, 02:17:27 pm
I am willing to help, if versioned linking might/will be accepted by FPC devs.

First prove that something works, then talk about accepting.

Quote
I have already made a FPC source scanner to find all libc-calls based on this header file.
Based on headers from: https://github.com/wheybags/glibc_version_header/blob/master/version_headers/x64/force_link_glibc_2.27.h

That has been attempted before too, but is arch specific, and doesn't actually fix the real problem of C interfacing for libc purposes, namely the structures and macros (like FD_SET etc).

Quote
Proposal.
All libc-calls (the externals) might be defined from an include file that has a versioned and an unversioned definition of every call. Would also cleanup the FPC sources a bit. As stated previously, care must be taken to include all libc CPU-OS combo's.

Too many CPU-OS combos and too many places where libc is linked to be practical (we had unit libc once and it was a nightmare), and as said this autogeneration only fixes the calls, not the rest including non Linux *nix that doesn't benefit from this.

I think a saner way would be to have a small patch to the linker backend of the compiler to do substitutions there based on a file ( symbol x in lib y should become  y@4234 in lib x). That can be kept out of tree easily to prove the concept.

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 25, 2023, 03:42:27 pm
Too many CPU-OS combos and too many places where libc is linked to be practical

all we need to care about is x86-64 Linux, everything else can be left to fend for itself. if that works, then expand out to cover other variants later on.

use a simple include file, containing something like:

{$IF not DECLARED(symbol_libc_start_main)}
  {$IFDEF LINUX and x86_64}
    const symbol_libc_start_main='__libc_start_main@GLIBC_2.2.5';
          symbol_dlopen         ='dlopen@GLIBC_2.2.5';
          symbol_dlsym          ='dlsym@GLIBC_2.2.5';
          // etc...
  {$ELSE}
    const symbol_libc_start_main='__libc_start_main';
          symbol_dlopen         ='dlopen';
          symbol_dlsym          ='dlsym';
          // etc...
  {$ENDIF}
{$ENDIF}

(yes, i know i have the $IF syntax all messed up!)

then for every external statement substitute:

... external 'libc' name symbol_xxxx
or
... external 'libdl' name symbol_xxxx
as required.

the include file can be included at the top of every file that contains externals.

the necessary version number for each symbol can be extracted relatively easily from libc.so.6 using readelf.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: abouchez on July 25, 2023, 04:03:15 pm
Proposal.
All libc-calls (the externals) might be defined from an include file that has a versioned and an unversioned definition of every call. Would also cleanup the FPC sources a bit. As stated previously, care must be taken to include all libc CPU-OS combo's.
This include file could define such a constant:
https://github.com/synopse/mORMot2/commit/053b098c398f8f265ce148796aae6da4bc09dc69
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 25, 2023, 05:47:40 pm
But can someone please *exactly* explain in a private mail to michael@freepascal.org why dlopen() would need to be versioned ?

Each exported symbol in glibc has defined behavior, ABI, and API for a specific version only.  Some exported functions (and other symbols) have changed in ways that break existing source code and binaries and which could not be predicted in advance.  There is no guarantee that they won't have breaking changes in the future (any of them including dlopen).

What is symbol versioning good for? Do I need it?
https://sourceware.org/glibc/wiki/FAQ#What_is_symbol_versioning_good_for.3F__Do_I_need_it.3F

Quote
Symbol versioning solves problems that are related to interface changes. One version of an interface might have been introduced in a previous version of the GNU C library but the interface or the semantics of the function has been changed in the meantime...
We don't advise building without symbol versioning, since you lose binary compatibility - forever! The binary compatibility you lose is not only against the previous version of the GNU libc but also against all future versions. This means that you will not be able to execute programs that others have compiled.

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on July 26, 2023, 01:50:29 am
the necessary version number for each symbol can be extracted relatively easily from libc.so.6 using readelf.

Each FPC rtl interface declaration for glibc (i.e. FPC glibc header translations) must be used with a compatible symbol version in the glibc library.  Is there confidence that all the FPC glibc interface declarations are API compatible with the "base" versions of the glibc symbols?

A related, but separate question:  Is there confidence that the behavior of the "base" version of the symbols is compatible with the way FPC expects it to behave?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 26, 2023, 03:30:29 am
see here:
https://forum.lazarus.freepascal.org/index.php/topic,58888.msg485518.html#msg485518 (https://forum.lazarus.freepascal.org/index.php/topic,58888.msg485518.html#msg485518)

there are only about 30 sets of base names in glibc where different versions have different entry points, and most of these are not used in the RTL.

the assumption must be that the current FPC RTL has been written to be compatible with the BASE version of each symbol. if not, we would have seen widespread reports of failures from the many thousands of FPC/Lazarus users out there   ;)


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on July 26, 2023, 09:04:32 am
the necessary version number for each symbol can be extracted relatively easily from libc.so.6 using readelf.

Each FPC rtl interface declaration for glibc (i.e. FPC glibc header translations) must be used with a compatible symbol version in the glibc library.  Is there confidence that all the FPC glibc interface declarations are API compatible with the "base" versions of the glibc symbols?

First: there is no specific glibc header. Multiple parts import symbols from libc in isolation in a cross *nix matter. That ranges from Linux,*BSD,OSX to AIX, Solaris to half *nixes like BeOS and in the past Netware-libc.  This roughly follows header divisions in *libc too.

So the base RTL imports base calls like mmap,seek and read/write. (see rtl/unix/bunxh.inc) _IF_ it doesn't use syscalls, which are default. The socket units import socket related calls, the optional memory manager substitute imports malloc/free/realloc, one of several DNS resolves import libc, the Users package does the user and password stuff etc etc, unit DL manages dynamic library loading etc. There is no single unified glibc header, and those local declarations usually have a OS specific part for header parts with variation among OSes, and use *nix wide declarations for the rest, possibly even ifdefed for arch etc.

This is all to minimize maintenance and keep a bit of overview.

I expect no problems with the calls themselves. Symbol versioning would be more about fixating a certain version for a while (and cross distro) because FPC doesn't adapt automatically to different headers (with different structs, constants and macros). So the same build on an old Debian STABLE and the newest rolling ARCH can be seen as using the same headers etc, but linking  to the same default symbol (_read, _write etc), whose version might differ between those distros.

For symbol versioning to improve anything, a debian old stable and a new a flashy distro would both have to implement exactly the same base subset. i.e. using the exact same definition of the STAT record/struct etc.   Or adding some extra constant to an ORed set of values, or change the implementation of some macro.

But as said, nothing of this is proven. It is all theory. Something else might become the next bottleneck preventing cross distro binary generation like changes to startup code (libc initialization!), or linker changes. The problems are not even properly investigated even, it is all anecdotal. We don't even have proper knowledge about omitting the syscalls, even though that option exists for 19 years.

At this stage, interested users should do a long term test to see if any proposed changes or strategy really improve cross-distro compatibility for a longer term (e.g. release cycles). To ease that it would be wise to do a setup with minimal source changes to make it easier to rebase to trunk regularly. See my previous post.

Things like reordering all sources to specific OS-target combinations is out of the question. It is way to invasive for what it solves and hurts all  *nixes for a Linux problem. Same with decorating all symbols in sources. As soon as multiple distros with differing base versions happen during some transition (and the 5+ year window that old LTSes die out), that is an mess.

A mapping file that works on the .o writing backend would be more logical, and could be switched in such cases.

Quote
A related, but separate question:  Is there confidence that the behavior of the "base" version of the symbols is compatible with the way FPC expects it to behave?

See above. I don't really think it is detail behaviour of the call itself, but more pinning a certain version that match the translated headers definition, and less tension about what to do, update the header for newer distros, or keep it working with LTSes.
 
The base call prototypes themselves work across *nix mostly OSX, *BSD and Linux. But BSD usually saves compatibility breaks for major version transitions so this problem is easier to manage, and also has the seemless COMPAT mechanisms to keep binaries built on older binaries working on newer.  (but the FPC BSD ports recently suffer from the LLVM transitions).

One could argue though that during a base version transition there should be simply two FPC releases to pick from.

Also who is going to manage all this long term, monitor the glibc lists to provide updates or alert on changes etc etc?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on July 27, 2023, 07:16:30 am
I think a saner way would be to have a small patch to the linker backend of the compiler to do substitutions there based on a file ( symbol x in lib y should become  y@4234 in lib x). That can be kept out of tree easily to prove the concept.

marcov: that is an excellent idea. are you able to do this, or able to offer guidance on how to do this?


can we achieve any useful result using:
   --allow-shlib-undefined
or
   --no-allow-shlib-undefined
to prevent the compile-time linker from appending @GLIBC... to symbols in the Dynamic Symbol Table? while this method is not recommended by the GLIBC developers, i think it is still working pursuing as a parallel project that may provide some utility and knowledge.

addendum 1: i may have the linker switch --allow-shlib-undefined wrong here, i'm wanting to talk about the switch that allows unversioned symbols to remain unversioned

[...]
For symbol versioning to improve anything, a debian old stable and a new a flashy distro would both have to implement exactly the same base subset. i.e. using the exact same definition of the STAT record/struct etc.   Or adding some extra constant to an ORed set of values, or change the implementation of some macro.
[...]
Also who is going to manage all this long term, monitor the glibc lists to provide updates or alert on changes etc etc?

"a debian old stable and a new a flashy distro would both have to implement exactly the same base subset"

this is exactly what Florian Weimer has promised us - for a given architecture, the original BASE set (@GLIBC_2.2.5) will remain fixed in stone for life. as new functions are added, they will be brought into the BASE set with later @GLIBC_2.xx version numbers, but there is no compulsion for anyone to use those new functions.

"who is going to manage all this long term"

for a given architecture there is no need for long term management. the original BASE set is fixed in stone. it will never change. it needs to be arrived at once, through a relatively simple process. after that, we can forget it and go back to using FPC/Lazarus to write useful programs for sharing with the wider community.


cheers,
rob   :-)

addendum 2: what if external would accepted a further (optional) parameter, being one of: linkbase, linkauto, linknone? these would yield for the example dlopen, respectively: 'dlopen@GLIBC_2_2_5', 'dlopen@GLIBC_2.34', 'dlopen'.

addendum 3: linkbase could trigger using readelf to extract the base version number for a given symbol at compile-time, hence no need to construct and have stored any translation table.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on August 04, 2023, 09:16:52 pm
a new approach, based on information provided in the thread:
https://forum.lazarus.freepascal.org/index.php/topic,64158.0.html (https://forum.lazarus.freepascal.org/index.php/topic,64158.0.html)

this involves modifying the function pd_external() in the file pdecsub.pas to automatically intercept and add versioning to selected glibc symbols:

Code: Pascal  [Select][+][-]
  1. // modify the file /usr/share/fpcsrc/3.2.2/compiler/pdecsub.pas
  2. // adding the code below to the end of pd_external() at approximately line 2340.
  3.  
  4. procedure pd_external(pd:tabstractprocdef);
  5. {
  6.   If import_dll=nil the procedure is assumed to be in another
  7.   object file. In that object file it should have the name to
  8.   which import_name is pointing to. Otherwise, the procedure is
  9.   assumed to be in the DLL to which import_dll is pointing to. In
  10.   that case either import_nr<>0 or import_name<>nil is true, so
  11.   the procedure is either imported by number or by name. (DM)
  12. }
  13. var
  14.   hs, sym_name, ver_name : string;                     // **** added sym_name and ver_name ****
  15.   v:Tconstexprint;
  16.   is_java_external: boolean;
  17. begin
  18. ...
  19. ...
  20. ...
  21.              import_name:=stringdup(get_stringconst);
  22.              include(procoptions,po_has_importname);
  23.              if import_name^='' then
  24.                message(parser_e_empty_import_name);
  25.            end;
  26.         end;
  27.  
  28. //      ******** added code follows ********
  29. //      writeln('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
  30.  
  31.         if assigned(import_name) then sym_name:=import_name^
  32.                                  else sym_name:=proc_get_importname(tprocdef(pd));
  33.                                              
  34.         ver_name:='' ;
  35.         if sym_name='__libc_start_main' then ver_name:='__libc_start_main@GLIBC_2.2.5';
  36.         if sym_name='dlopen'            then ver_name:='dlopen@GLIBC_2.2.5';
  37.         if sym_name='dlclose'           then ver_name:='dlclose@GLIBC_2.2.5';
  38.         if sym_name='dlsym'             then ver_name:='dlsym@GLIBC_2.2.5';
  39.         if sym_name='dlvsym'            then ver_name:='dlvsym@GLIBC_2.2.5';
  40.         if sym_name='dladdr'            then ver_name:='dladdr@GLIBC_2.2.5';    
  41.         if sym_name='dlerror'           then ver_name:='dlerror@GLIBC_2.2.5';
  42.         if sym_name='dlinfo'            then ver_name:='dlinfo@GLIBC_2.2.5';
  43.        
  44.         if ver_name<>'' then begin
  45.                                import_name:=stringdup(ver_name);
  46.                                writeln('%%%% versioning ', sym_name, ' >> ', ver_name)
  47.                              end
  48. //
  49. // remember to also add the symlink libdl.so -> libdl.so.2 using:
  50. //
  51. // sudo ln -s /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/libdl.so
  52. //
  53.  
  54. //      writeln('------------------------------------------------------------------------')
  55. //      ******** end of added code ********
  56.     end;
  57. end;

after modifying, create a symlink from libdl.so to libdl.so.2 using:
sudo ln -s /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/libdl.so

then rebuilding the RTL and compiler using rebuild.sh (from Fred vS) placed in the /usr/share/fpcsrc/3.2.2 directory:
Code: Bash  [Select][+][-]
  1. #!/bin/sh
  2. COMPILER=fpc
  3. make clean
  4. make all FPC=$COMPILER OPT="-Fl/usr/local/lib"
  5. make FPC=$COMPILER install INSTALL_PREFIX=/usr/

you will likely need to add other symbols that also need versioning as 2.2.5, and of course the version number is specific to x86-64 Linux. conditionals should be added around the code to ensure this.

while currently hard-coded, in theory the correct version information could be extracted on-the-fly using calls to readelf, but i have not tried this yet.

ideally, the added functionality within pd_external() should be turned on/off using a compiler switch, as it is normally only going to be needed when compiling the compiler, RTL and LCL. but i don't know how to do this (yet). alternatively, symbols that you want to BASE version could have a unique version added, such as dlopen@BASE, where @BASE would be substituted with the correct version number. but this would then require the work of going through and modifying every external statement in the RTL and LCL.

enjoy!

cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: WayneSherman on August 06, 2023, 02:51:54 am
for a given architecture there is no need for long term management. the original BASE set is fixed in stone. it will never change. it needs to be arrived at once, through a relatively simple process. after that, we can forget it and go back to using FPC/Lazarus to write useful programs for sharing with the wider community.

a new approach...involves modifying the function pd_external() in the file pdecsub.pas to automatically intercept and add versioning to selected glibc symbols...

Since this only needs to be done once, isn't the most direct and simple solution to manually add the symbol version to the external function declarations?:

Code: Pascal  [Select][+][-]
  1. function dlopen(__file:Pchar; __mode:longint):pointer;cdecl;external dllib name 'dlopen@GLIBC_2.2.5';
  2. //or like fredvs did
  3. function dlopen(__file:Pchar; __mode:longint):pointer;cdecl;external dllib name 'dlopen' + LIBC_SUFFIX;

That way if changes are made to the declarations in the future, you see immediately which version is being called (or at least that there might be a specific version if LIBC_SUFFIX is set).  It seems to me that modifying "pdecsub.pas" to hide versioning "magic" in the compiler will produce effects that require special knowledge (and if you don't happen to know about the side effects it is easier to introduce bugs and harder to debug problems).

What if someone declares a specific version in their own code.  Does the "pdecsub.pas" change cause a problem for this?:
Code: Pascal  [Select][+][-]
  1. function dlopen_v238(__file:Pchar; __mode:longint):pointer;cdecl;external dllib name 'dlopen@GLIBC_2.3.8';
  2. // granted instead of static loading, it would be better to dynamically load any
  3. // modern libc functions using gnu_get_libc_version(), dlopen(), and dlsym()
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on August 06, 2023, 05:07:54 pm
Since this only needs to be done once, isn't the most direct and simple solution to manually add the symbol version to the external function declarations?

this is just an experimental alternative. but there are a few unique advantages:

1. you don't need to track down external statements from several different places in the RTL, all symbol versioning is in a single place,
2. it is immune to future changes or additions to the RTL that may slip through unnoticed,
3. the versioning information can potentially be loaded from a file by the compiler, hence can be made editable without rebuilding the compiler + RTL.
addendum: while you can edit the versioning information without rebuilding the RTL, as the RTL is pre-built the already versioned symbols in it (from when it was last built) would not change when a user program was built. editing the versioning list file would just affect symbols in the user-code. hence the binary you created could (quite validly) have two versions of the same symbol present in its Dynamic Symbol Table. (9-august-2023)

a hybrid of the two approaches would be for the code in pd_external() to be triggered by any symbol ending in '@BASE', and then specify that every external in the RTL must end this way - there is no good reason why the RTL should need to use anything other than the BASE versions of glibc functions.

What if someone declares a specific version in their own code.  Does the "pdecsub.pas" change cause a problem for this?:

// granted instead of static loading, it would be better to dynamically load any
// modern libc functions using gnu_get_libc_version(), dlopen(), and dlsym()

symbols that are already versioned are left untouched. i agree 100% that the RTL etc should be rewritten so that it uses dlopen() and dlym() instead of external, it would be a little bit more work but produce a much cleaner result.

---

below is an updated version of the pd_external() code that cleans up the way symbols are checked for translation. you can see how STT could instead be a variable, with content loaded in the initialization section at the end of the unit's source from a text file:

Code: Pascal  [Select][+][-]
  1. procedure pd_external(pd:tabstractprocdef);
  2. {
  3.   If import_dll=nil the procedure is assumed to be in another
  4.   object file. In that object file it should have the name to
  5.   which import_name is pointing to. Otherwise, the procedure is
  6.   assumed to be in the DLL to which import_dll is pointing to. In
  7.   that case either import_nr<>0 or import_name<>nil is true, so
  8.   the procedure is either imported by number or by name. (DM)
  9. }
  10. const STT='$__libc_start_main@GLIBC_2.2.5'+    // '$' before each versioned symbol name
  11.           '$dlopen@GLIBC_2.2.5'+
  12.           '$dlclose@GLIBC_2.2.5'+
  13.           '$dlsym@GLIBC_2.2.5'+
  14.           '$dlvsym@GLIBC_2.2.5'+
  15.           '$dladdr@GLIBC_2.2.5'+  
  16.           '$dlerror@GLIBC_2.2.5'+
  17.           '$dlinfo@GLIBC_2.2.5'+'$';           // MUST also be a trailing '$' at very end
  18.  
  19. var
  20.   hs, sym_name, ver_name : string;
  21.   I:integer;
  22.   v:Tconstexprint;
  23.   is_java_external: boolean;
  24. begin
  25.     ...
  26.     ...
  27.     ...
  28.              import_name:=stringdup(get_stringconst);
  29.              include(procoptions,po_has_importname);
  30.              if import_name^='' then
  31.                message(parser_e_empty_import_name);
  32.            end;
  33.         end;  
  34.  
  35. //      ******** added code follows ********    
  36. //      writeln('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
  37.  
  38.         if assigned(import_name) then sym_name:=import_name^
  39.                                  else sym_name:=proc_get_importname(tprocdef(pd));
  40. //      writeln('symbol = ', sym_name);        
  41.  
  42.         ver_name:='';
  43.         if pos('@', sym_name)=0 then        // no versioning present -> attempt translation
  44.         begin
  45.           I:=pos('$'+sym_name+'@', STT);    // try to find symbol in Symbol Translation Table
  46.           if I<>0 then                      // match found, note that it starts with '$'
  47.           repeat
  48.             inc(I);                         // index of each character in versioned symbol name
  49.             ver_name:=ver_name+STT[I]       // append character to ver_name
  50.           until STT[I+1]='$'                // repeat until next character to retrieve is a '$'
  51.         end;
  52.        
  53.         if ver_name<>'' then begin
  54.                                import_name:=stringdup(ver_name);
  55.                                writeln('%%%% versioning ', sym_name, ' >> ', ver_name)
  56.                              end
  57. //
  58. // remember to also add the symlink libdl.so -> libdl.so.2 using:
  59. // sudo ln -s /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/libdl.so
  60. //
  61. //      writeln('------------------------------------------------------------------------')
  62. //      ******** end of added code ********
  63.     end;
  64. end;


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on August 06, 2023, 05:19:36 pm
Since this only needs to be done once, isn't the most direct and simple solution to manually add the symbol version to the external function declarations?:

The declarations are shattered over many files and packages and are not Linux specific, but mostly for all *nix and even some half nixes like BeOS

In any case, it would preferable to solve this without source or language modifications, e.g. in the ELF object writer or so.
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on August 06, 2023, 05:36:23 pm
The declarations are shattered over many files and packages and are not Linux specific, but mostly for all *nix and even some half nixes like BeOS

In any case, it would preferable to solve this without source or language modifications, e.g. in the ELF object writer or so.

does BeOS suffer from symbol versioning as well?

one problem with attacking the problem at the ELF end is that then you will trample on any symbols that the programmer wants to be a specific version. for instance, the RTL may need to use an older version of memcpy, while someone writing a program using FPC may depend on a newer version of memcpy. the only ways around this are at the level of either the RTL source, or at the compiler.

there is also a problem with a couple of symbols, setenv and __cxa_finalize. both seem to be referenced from unknown places, with only my fake libdl.so catching them.


cheers,
rob   :-)
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: Seenkao on October 25, 2023, 07:02:04 pm
Без "танцев с бубном" данная проблема так и не была решена?

Почему, в новых системах происходит указание на новую ссылку? Почему компилируя программу в "старой" системе, я не получаю подобных ошибок?

Google translate:
Without "dancing with a tambourine" this problem was never solved?

Why does a new link point to a new link in new systems? Why do I not get similar errors when compiling a program on the “old” system?
Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: marcov on October 25, 2023, 08:16:31 pm
does BeOS suffer from symbol versioning as well?

Maybe. It had glibc at one point, but has gone through several iterations.

FreeBSD and *BSD has a more generational model, with very hard compatibility within a major version cycle (2-4 years), and not much guaranteed outside that.

Quote
one problem with attacking the problem at the ELF end is that then you will trample on any symbols that the programmer wants to be a specific version. for instance, the RTL may need to use an older version of memcpy, while someone writing a program using FPC may depend on a newer version of memcpy. the only ways around this are at the level of either the RTL source, or at the compiler.

FPC doesn't use memcpy. And such far fetched scenarios can be tackled by the programmer that needs them.

I'm more interested in keeping the standard distribution working out of the box for most users, and rather avoid complex and possible fragile workarounds to theoretical increase, but practically decrease that group.

Quote
there is also a problem with a couple of symbols, setenv and __cxa_finalize. both seem to be referenced from unknown places, with only my fake libdl.so catching them.

Might be ld-linux or glibc startup code. Not necessarily FPC.

Title: Re: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
Post by: robert rozee on October 25, 2023, 10:57:11 pm
there is also a problem with a couple of symbols, setenv and __cxa_finalize. both seem to be referenced from unknown places, with only my fake libdl.so catching them.

Might be ld-linux or glibc startup code. Not necessarily FPC.

my posting you are replying to was nearly 3 months ago, the world has moved on quite a bit since then! the more recent pd_external() patch manages to catch pretty much everything that earlier solutions missed.

although i do still have a soft spot for the fake libdl.so solution. it was elegant, but alas went against the advice of the GLIBC developers   O:-)


cheers,
rob   :-)
TinyPortal © 2005-2018