Discussion:
Runtime loader issue
Lucas Nali de Magalhães
2018-05-11 06:04:48 UTC
Permalink
Again, you are missing that the situation would happen just the same if
the base compiler is GCC 4.2.1 and not Clang.
FreeBSD could have stayed in-step with the times.
FreeBSD or any other system could be updated the GCC version for every
release and there would still appear a newer GCC version that requires
an even newer libgcc_s.so in the release life time. Heck, the very same
problem happens in the other direction as well, i.e. if you are forced
to use an *older* GCC and pick up its libgcc_s.so.
Hi.

This libgcc issue is a little recurrent here in FreeBSD. I remember other email threads talking about it. The summary I remember is that we must go the way Linux does it, I think. It was thoroughly explained in past threads.

As GCC was/is omnipresent in Unix like systems most of the other projects have standard ways to use the libgcc. I used to think in new libgcc as a drop in replacement for older ones. I know this is a bit simplistic. I remember Linux usually uses just one libgcc at a time, too. This is the winning answer usually here, too. In fact I remember that new libgcc versions triggers systems recompilations for safety reasons.

The use of libgcc in FreeBSD makes the procedure unusually complex many times here. It's a source of many problems. This one is one more to add to the list. This just occurred to me now. Please, keep in mind that the case here is caused by the odd use given to this library here.

Lc
--
rollingbits — 📧 ***@gmail.com 📧 ***@terra.com.br 📧 ***@yahoo.com 📧 ***@globo.com 📧 ***@icloud.com
Steve Kargl
2018-05-10 15:15:22 UTC
Permalink
On Thu, May 10, 2018 at 2:45 AM, Steve Kargl <
In review PR 228007, it came to my attention some individuals are
mis-characterizing a FreeBSD loader issue as "gfortran's FreeBSD
issue". See
Indeed. I've tried to make it clear it is a name conflict with libgcc
in my own bug reports on the subject.
https://lists.freebsd.org/pipermail/freebsd-fortran/2018-May/000124.html
The problem can be summarized by the following
...
gfortran7 is installed from ports/lang/gcc7. This is not
a "gfortran's FreeBSD issue". This is a FreeBSD loader issue.
Specifically, there is a shared library name clash.
% ldconfig -r | grep gcc_
6:-lgcc_s.1 => /lib/libgcc_s.so.1
716:-lgcc_s.1 => /usr/local/lib/gcc7/libgcc_s.so.1
Yep.
See https://wiki.freebsd.org/libgcc%20problem
Interesting page. I was aware that in the past you tried working
out a solution to the problem. I did not realize you docoumented
the issue. A few corrections to your wiki page.

1) The correct spelling of the name of the language is Fortran (with a
capital F). It has been the official standard spelling since Fortran
90.

2) You have "... to always support quad math (*8) and ...". Quad
precision in gfortran is REAL(16) (the REAL*16 notation is nonstandard).

3) "subsitute" is normally spelled with an extra 't'. :-)
So, the runtime loader finds 6 instead of 716, tries to link,
fails, and issues an error message. There are a number ways to
fix this issue.
1) By far, the best solution would be to stop hijacking the libgcc
name in libraries installed on FreeBSD that are not related to
actual GCC software.
Agreed, however this has the side effect of meaning conflicts with libraries
between clang and gcc libs. Notably gfortran and flang use different
conventions for I/O :(
See http://people.FreeeBSD.org/~db/fortran_libs.txt
Page doesn't appear to exist? If I go to

https://people.freebsd.org/homepage.html

you're not listed.
Why not use libcompiler_rt_s.so.1 (or libclang_s.so.1)? Yes, I'm
aware that clang does not work on all archs and the ancient gcc
lives on.
I've argued for this as well and frankly I still think it is the best
solution all around.
2) Given the expected push back againt solution 1), this solution
proposes bumping the library version for /lib/libgcc_s.so.1 from
1 to some larger value, say, 10. It is unlikely that GCC will
bump its shared library number anytime soon. GCC bumped it from
0 to 1 some 16 years ago.
https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=43316
This solution, however, papers over the general problem with
name clashes.
Yep. I know work is slowly being done to modernise our libgcc already
but the toolchain folks are busy...
3) This solution is to actually fix the runtime loader. If an error
occurs with loading a shared library, then iterate over the entries
in the hints file to check to see if another hint would satisfy
the linking. Here, instead of issuing the above error, the loader
would find entry 716, and load the correct libgcc_s.so.1.
This breaks if the bad libgcc is already linked. We'd have to rip
out the original bindings at run time, then re-bind to a new libgcc.
I looked at the rtld code months ago. Nasty and silly.
Admittedly, I haven't looked to see how difficult this solution
would be.
Very ;)
Just started reading the source code. Don't scare the unwary. :-)
--
Steve
Kurt Lidl
2018-05-10 15:23:39 UTC
Permalink
Post by Steve Kargl
Agreed, however this has the side effect of meaning conflicts with libraries
between clang and gcc libs. Notably gfortran and flang use different
conventions for I/O :(
See http://people.FreeeBSD.org/~db/fortran_libs.txt
Page doesn't appear to exist? If I go to
https://people.freebsd.org/homepage.html
you're not listed.
There's one too many "e" characters in the given URI.

Correct URI: http://people.FreeBSD.org/~db/fortran_libs.txt

-Kurt
Steve Kargl
2018-05-10 17:38:16 UTC
Permalink
Post by Kurt Lidl
Post by Steve Kargl
Agreed, however this has the side effect of meaning conflicts with libraries
between clang and gcc libs. Notably gfortran and flang use different
conventions for I/O :(
See http://people.FreeeBSD.org/~db/fortran_libs.txt
Page doesn't appear to exist? If I go to
https://people.freebsd.org/homepage.html
you're not listed.
There's one too many "e" characters in the given URI.
Correct URI: http://people.FreeBSD.org/~db/fortran_libs.txt
Ah, thanks! I simply copy-n-pasted the link, then went to
the homepage.html via a bookmark.

The incompatibility in IO runtimes between gfortran and
flang is a minor issue for anyone using actual modern
Fortran, and in particular, Fortran's MODULE feature.

% cat m.f90
module foo
implicit none
real :: pi = 3.14
contains
function real_pi() result(p)
real p
p = atan(1.)
end function real_pi
end module foo
% gfortran6 -c m.f90
% nm m.o
0000000000000000 D __foo_MOD_pi
0000000000000000 T __foo_MOD_real_pi
% file foo.mod
foo.mod: gzip compressed data, from Unix
% flang -c m.f90
% nm m.o
0000000000000000 r .C288_foo_real_pi_
0000000000000000 r .LCPI1_0
0000000000000000 D _foo_8_
0000000000000000 T foo_
0000000000000010 T foo_real_pi_
% file foo.mod
foo.mod: ASCII text

foo.mod can be thought of as a pre-compile header.
It will encode the named constant pi and a signature
for the function real_pi. The object files contain
name-mangled entry points for the function. The
Fortran Standard(s) do not specify implementation detail,
so there is an incompatibility between not only
gfortran and flang, but all Fortran compiler vendors.
--
Steve
Diane Bruce
2018-05-10 16:47:08 UTC
Permalink
Post by Steve Kargl
On Thu, May 10, 2018 at 2:45 AM, Steve Kargl <
...
Post by Steve Kargl
Yep.
See https://wiki.freebsd.org/libgcc%20problem
Interesting page. I was aware that in the past you tried working
out a solution to the problem. I did not realize you docoumented
the issue. A few corrections to your wiki page.
1) The correct spelling of the name of the language is Fortran (with a
capital F). It has been the official standard spelling since Fortran
90.
Fixed
Post by Steve Kargl
2) You have "... to always support quad math (*8) and ...". Quad
precision in gfortran is REAL(16) (the REAL*16 notation is nonstandard).
I think I got it right this time...
Post by Steve Kargl
3) "subsitute" is normally spelled with an extra 't'. :-)
OOOps ;) fixed
Post by Steve Kargl
Very ;)
Just started reading the source code. Don't scare the unwary. :-)
;)
Post by Steve Kargl
--
Steve
Diane
--
- ***@FreeBSD.org ***@db.net http://www.db.net/~db
Tijl Coosemans
2018-05-10 16:21:51 UTC
Permalink
In review PR 228007, it came to my attention some individuals are
mis-characterizing a FreeBSD loader issue as "gfortran's FreeBSD
issue". See
https://lists.freebsd.org/pipermail/freebsd-fortran/2018-May/000124.html
The problem can be summarized by the following
% gfortran7 -o z h.f90
% ./z
/lib/libgcc_s.so.1: version GCC_4.8.0 required by \
/usr/local/lib/gcc7/libgfortran.so.4 not found
gfortran7 is installed from ports/lang/gcc7. This is not
a "gfortran's FreeBSD issue". This is a FreeBSD loader issue.
Specifically, there is a shared library name clash.
% ldconfig -r | grep gcc_
6:-lgcc_s.1 => /lib/libgcc_s.so.1
716:-lgcc_s.1 => /usr/local/lib/gcc7/libgcc_s.so.1
% ldd z
libgfortran.so.4 => /usr/local/lib/gcc7/libgfortran.so.4 (0x200645000)
libm.so.5 => /lib/libm.so.5 (0x200a17000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x200a4b000)
libquadmath.so.0 => /usr/local/lib/gcc7/libquadmath.so.0 (0x200a63000)
libc.so.7 => /lib/libc.so.7 (0x200ca3000)
So, the runtime loader finds 6 instead of 716, tries to link,
fails, and issues an error message. There are a number ways to
fix this issue.
1) By far, the best solution would be to stop hijacking the libgcc
name in libraries installed on FreeBSD that are not related to
actual GCC software.
% ls -l /lib/libgcc* /usr/lib/libgcc*
(trimming lines)
/lib/libgcc_s.so.1
/usr/lib/libgcc_eh.a
/usr/lib/libgcc_eh_p.a
Why not use libcompiler_rt_s.so.1 (or libclang_s.so.1)? Yes, I'm
aware that clang does not work on all archs and the ancient gcc
lives on.
2) Given the expected push back againt solution 1), this solution
proposes bumping the library version for /lib/libgcc_s.so.1 from
1 to some larger value, say, 10. It is unlikely that GCC will
bump its shared library number anytime soon. GCC bumped it from
0 to 1 some 16 years ago.
https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=43316
This solution, however, papers over the general problem with
name clashes.
3) This solution is to actually fix the runtime loader. If an error
occurs with loading a shared library, then iterate over the entries
in the hints file to check to see if another hint would satisfy
the linking. Here, instead of issuing the above error, the loader
would find entry 716, and load the correct libgcc_s.so.1.
Admittedly, I haven't looked to see how difficult this solution
would be.
4) Bump the shared library number of the individual ports. As a proof
of concept, I've done this with ports/lang/gcc6.
% cat /usr/ports/lang/gcc6/files/patch-t-slibgcc
--- libgcc/config/t-slibgcc.orig 2018-05-08 12:47:42.334495000 -0700
+++ libgcc/config/t-slibgcc 2018-05-08 12:45:26.872312000 -0700
@@ -20,7 +20,7 @@
SHLIB_EXT = .so
-SHLIB_SOVERSION = 1
+SHLIB_SOVERSION = 2
% ldconfig -r | grep gcc_
6:-lgcc_s.1 => /lib/libgcc_s.so.1
716:-lgcc_s.1 => /usr/local/lib/gcc7/libgcc_s.so.1
766:-lgcc_s.2 => /usr/local/lib/gcc6/libgcc_s.so.2
% gfortran6 -o z h.f90
% ./z
hello
% ldd z
libgfortran.so.3 => /usr/local/lib/gcc6/libgfortran.so.3 (0x200645000)
libm.so.5 => /lib/libm.so.5 (0x20096c000)
libgcc_s.so.2 => /usr/local/lib/gcc6/libgcc_s.so.2 (0x2009a0000)
libquadmath.so.0 => /usr/local/lib/gcc7/libquadmath.so.0 (0x200bb7000)
libc.so.7 => /lib/libc.so.7 (0x200df7000)
This works for this particular name conflict. Hopefully, FreeBSD
never needs to bump /lib/libgcc_s.so.1 to /lib/libgcc_s.so.2. This,
however, introduces an incompatibility with what is actually distributed
by GCC.
Finally, can people stop referring to the above error as
"gfortran's FreeBSD issue". This is a FreeBSD runtime loader issue.
libgcc_s.so implements the _Unwind_* API to handle stack unwinding. This
code is shared between all compilers and languages because the stack can
contain frames from different compilers and languages. So, you cannot
change the name or version of the library.

I've been testing the attached patch in combination with the ports tree
patch from https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=228046.

The patch makes three changes to /etc/rc.d/ldconfig:
1) Use 'sort -r' so /usr/local/lib/gcc7 appears before /usr/local/lib/gcc6.
2) Move hardcoded paths like /lib and /usr/lib to /etc/defaults/rc.conf
so the order relative to other paths can be configured.
3) Change the order of ldconfig_local_dirs and ldconfig_paths so /lib and
/usr/lib appear last. This brings rc.d/ldconfig in line with compilers
and rtld(1) which also search /lib and /usr/lib last.
Steve Kargl
2018-05-10 17:21:59 UTC
Permalink
Post by Tijl Coosemans
So, the runtime loader finds 6 instead of 716, tries to link,
fails, and issues an error message. There are a number ways to
fix this issue.
1) By far, the best solution would be to stop hijacking the libgcc
name in libraries installed on FreeBSD that are not related to
actual GCC software.
% ls -l /lib/libgcc* /usr/lib/libgcc*
(trimming lines)
/lib/libgcc_s.so.1
/usr/lib/libgcc_eh.a
/usr/lib/libgcc_eh_p.a
Why not use libcompiler_rt_s.so.1 (or libclang_s.so.1)? Yes, I'm
aware that clang does not work on all archs and the ancient gcc
lives on.
2) Given the expected push back againt solution 1), this solution
proposes bumping the library version for /lib/libgcc_s.so.1 from
1 to some larger value, say, 10. It is unlikely that GCC will
bump its shared library number anytime soon. GCC bumped it from
0 to 1 some 16 years ago.
https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=43316
This solution, however, papers over the general problem with
name clashes.
libgcc_s.so implements the _Unwind_* API to handle stack unwinding. This
code is shared between all compilers and languages because the stack can
contain frames from different compilers and languages. So, you cannot
change the name or version of the library.
Well, yes one could change the name and/or shared library number.
All those other tools would then need to be adapted to look for
a renamed or number-bumped library. Yes, painful.
Post by Tijl Coosemans
I've been testing the attached patch in combination with the ports tree
patch from https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=228046.
1) Use 'sort -r' so /usr/local/lib/gcc7 appears before /usr/local/lib/gcc6.
2) Move hardcoded paths like /lib and /usr/lib to /etc/defaults/rc.conf
so the order relative to other paths can be configured.
3) Change the order of ldconfig_local_dirs and ldconfig_paths so /lib and
/usr/lib appear last. This brings rc.d/ldconfig in line with compilers
and rtld(1) which also search /lib and /usr/lib last.
This appears to work around the problem with libgcc_s.so.1.
It would be a welcomed solution to so-called "gfortran's
FreeBSD issue", but is does not solve the problem with name
clashes. It is possible to have two independent libraries
for independent projects where no shuffling of order in hints
will work.
--
Steve
Wojciech Puchar
2018-05-10 19:13:39 UTC
Permalink
just another - out of thousands - example that shared libraries are one
of the worst thing invented in computing.

Maybe except of single system wide shared library with constant interface.
On Thu, May 10, 2018 at 2:45 AM, Steve Kargl <
In review PR 228007, it came to my attention some individuals are
mis-characterizing a FreeBSD loader issue as "gfortran's FreeBSD
issue". See
https://lists.freebsd.org/pipermail/freebsd-fortran/2018-May/000124.html
The problem can be summarized by the following
% gfortran7 -o z h.f90
% ./z
/lib/libgcc_s.so.1: version GCC_4.8.0 required by \
/usr/local/lib/gcc7/libgfortran.so.4 not found
gfortran7 is installed from ports/lang/gcc7. This is not
a "gfortran's FreeBSD issue". This is a FreeBSD loader issue.
Specifically, there is a shared library name clash.
% ldconfig -r | grep gcc_
6:-lgcc_s.1 => /lib/libgcc_s.so.1
716:-lgcc_s.1 => /usr/local/lib/gcc7/libgcc_s.so.1
% ldd z
libgfortran.so.4 => /usr/local/lib/gcc7/libgfortran.so.4 (0x200645000)
libm.so.5 => /lib/libm.so.5 (0x200a17000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x200a4b000)
libquadmath.so.0 => /usr/local/lib/gcc7/libquadmath.so.0 (0x200a63000)
libc.so.7 => /lib/libc.so.7 (0x200ca3000)
So, the runtime loader finds 6 instead of 716, tries to link,
fails, and issues an error message. There are a number ways to
fix this issue.
1) By far, the best solution would be to stop hijacking the libgcc
name in libraries installed on FreeBSD that are not related to
actual GCC software.
% ls -l /lib/libgcc* /usr/lib/libgcc*
(trimming lines)
/lib/libgcc_s.so.1
/usr/lib/libgcc_eh.a
/usr/lib/libgcc_eh_p.a
Why not use libcompiler_rt_s.so.1 (or libclang_s.so.1)? Yes, I'm
aware that clang does not work on all archs and the ancient gcc
lives on.
2) Given the expected push back againt solution 1), this solution
proposes bumping the library version for /lib/libgcc_s.so.1 from
1 to some larger value, say, 10. It is unlikely that GCC will
bump its shared library number anytime soon. GCC bumped it from
0 to 1 some 16 years ago.
https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=43316
This solution, however, papers over the general problem with
name clashes.
3) This solution is to actually fix the runtime loader. If an error
occurs with loading a shared library, then iterate over the entries
in the hints file to check to see if another hint would satisfy
the linking. Here, instead of issuing the above error, the loader
would find entry 716, and load the correct libgcc_s.so.1.
Admittedly, I haven't looked to see how difficult this solution
would be.
4) Bump the shared library number of the individual ports. As a proof
of concept, I've done this with ports/lang/gcc6.
% cat /usr/ports/lang/gcc6/files/patch-t-slibgcc
--- libgcc/config/t-slibgcc.orig 2018-05-08 12:47:42.334495000 -0700
+++ libgcc/config/t-slibgcc 2018-05-08 12:45:26.872312000 -0700
@@ -20,7 +20,7 @@
SHLIB_EXT = .so
-SHLIB_SOVERSION = 1
+SHLIB_SOVERSION = 2
% ldconfig -r | grep gcc_
6:-lgcc_s.1 => /lib/libgcc_s.so.1
716:-lgcc_s.1 => /usr/local/lib/gcc7/libgcc_s.so.1
766:-lgcc_s.2 => /usr/local/lib/gcc6/libgcc_s.so.2
% gfortran6 -o z h.f90
% ./z
hello
% ldd z
libgfortran.so.3 => /usr/local/lib/gcc6/libgfortran.so.3 (0x200645000)
libm.so.5 => /lib/libm.so.5 (0x20096c000)
libgcc_s.so.2 => /usr/local/lib/gcc6/libgcc_s.so.2 (0x2009a0000)
libquadmath.so.0 => /usr/local/lib/gcc7/libquadmath.so.0 (0x200bb7000)
libc.so.7 => /lib/libc.so.7 (0x200df7000)
This works for this particular name conflict. Hopefully, FreeBSD
never needs to bump /lib/libgcc_s.so.1 to /lib/libgcc_s.so.2. This,
however, introduces an incompatibility with what is actually distributed
by GCC.
Finally, can people stop referring to the above error as
"gfortran's FreeBSD issue". This is a FreeBSD runtime loader issue.
https://reviews.freebsd.org/D11482
--
Steve
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-ports
Steve Kargl
2018-05-10 23:36:51 UTC
Permalink
In review PR 228007, it came to my attention some individuals are
mis-characterizing a FreeBSD loader issue as "gfortran's FreeBSD
issue". See
It seems we've had the same discussion 2 years ago. My time flies.

ttps://lists.freebsd.org/pipermail/freebsd-ports/2016-August/104384.html
--
Steve
Steve Kargl
2018-05-10 22:09:49 UTC
Permalink
Again, you are missing that the situation would happen just the same if
the base compiler is GCC 4.2.1 and not Clang.
FreeBSD could have stayed in-step with the times.
FreeBSD or any other system could be updated the GCC version for every
release and there would still appear a newer GCC version that requires
an even newer libgcc_s.so in the release life time. Heck, the very same
problem happens in the other direction as well, i.e. if you are forced
to use an *older* GCC and pick up its libgcc_s.so.
If, as you assert, FreeBSD's runtime loader isn't meant
to deal with name clashes, then why does ldconfig place
conflicting names into the list of hints?

% ldconfig -r | grep libgcc_s
6:-lgcc_s.1 => /lib/libgcc_s.so.1
716:-lgcc_s.1 => /usr/local/lib/gcc7/libgcc_s.so.1

Shouldn't ldconfig refuse to add 716 and complain
bitterly to the user to fix the conflict? Shouldn't
the documentation that comes with FreeBSD explain that
conflicting names are disallowed.

In looking at an objdump of lib/gcc7/libgfortran.so.4,
one finds

Dynamic Section:
NEEDED libquadmath.so.0
NEEDED libm.so.5
NEEDED libgcc_s.so.1
NEEDED libc.so.7
SONAME libgfortran.so.4
RPATH /usr/local/lib/gcc7

Why isn't the runtime loader looking in RPATH for the
libraries and then falling back to looking in the list
of hints.

I find your arguments to be somewhat diminished by the fact
FreeBSD re-uses a filename from a well-known and (much) older
software project, and somehow its the other project's fault
for the problem with a name clash.
--
Steve
Continue reading on narkive:
Loading...