Discussion:
how to fix lintian error: library-not-linked-against-libc
Add Reply
Steven Robbins
2025-01-26 05:10:01 UTC
Reply
Permalink
I've come to realise the ITK build has 15 libraries that lintian flags with
error library-not-linked-against-libc.

https://lintian.debian.org/tags/library-not-linked-against-libc.html[1]

The error description seems straightforward. But how does one solve this? I have to
assume that the linker would by default link with the libc (?), so perhaps the linker
invocation has options that suppress this? What would that be?

The (CMake-generated) link line does have a bunch of options. Nothing jumped out at me:

/usr/bin/c++ -fPIC -g -O2 -ffile-prefix-map=/home/steve/Packages/insighttoolkit/build-area/
insighttoolkit5-5.4.0=. -fstack-protector-strong -fstack-clash-protection -Wformat -
Werror=format-security -fcf-protection -Wdate-time
-D_FORTIFY_SOURCE=2 -I/usr/include/nifti -g1 -mtune=generic -march=corei7 -Wall -
Wcast-align -Wdisabled-optimization -Wextra -Wformat=2 -Winvalid-pch -Wno-format-
nonliteral -Wpointer-arith -Wshadow -Wunused -Wwrite-strings
-Wno-strict-overflow -Wno-deprecated -Wno-invalid-offsetof -Woverloaded-virtual -Wctad-
maybe-unsupported -Wstrict-null-sentinel -fno-sized-deallocation -msse2 -Wl,--
dependency-file=CMakeFiles/ITKColormap.dir/link.d -Wl,-z,re
lro -shared -Wl,-soname,libITKColormap-5.4.so.1 -o ../../../../lib/x86_64-linux-gnu/
libITKColormap-5.4.so.1 CMakeFiles/ITKColormap.dir/
itkScalarToRGBColormapImageFilter.cxx.o

The package builds 80 libraries in total, so 65 of them DON'T have this problem.

One example is:

/usr/bin/c++ -fPIC -g -O2 -ffile-prefix-map=/home/steve/Packages/insighttoolkit/build-area/
insighttoolkit5-5.4.0=. -fstack-protector-strong -fstack-clash-protection -Wformat -
Werror=format-security -fcf-protection -Wdate-time
-D_FORTIFY_SOURCE=2 -I/usr/include/nifti -g1 -mtune=generic -march=corei7 -Wall -
Wcast-align -Wdisabled-optimization -Wextra -Wformat=2 -Winvalid-pch -Wno-format-
nonliteral -Wpointer-arith -Wshadow -Wunused -Wwrite-strings
-Wno-strict-overflow -Wno-deprecated -Wno-invalid-offsetof -Woverloaded-virtual -Wctad-
maybe-unsupported -Wstrict-null-sentinel -fno-sized-deallocation -msse2 -w -Wl,--
dependency-file=CMakeFiles/ITKMetaIO.dir/link.d -Wl,-z,r
elro -shared -Wl,-soname,libITKMetaIO-5.4.so.1 -o ../../../../../../lib/x86_64-linux-gnu/
libITKMetaIO-5.4.so.1 CMakeFiles/ITKMetaIO.dir/metaUtils.cxx.o CMakeFiles/
ITKMetaIO.dir/metaArray.cxx.o CMakeFiles/ITKMetaIO.dir/metaAr
row.cxx.o CMakeFiles/ITKMetaIO.dir/metaBlob.cxx.o CMakeFiles/ITKMetaIO.dir/
metaCommand.cxx.o CMakeFiles/ITKMetaIO.dir/metaContour.cxx.o CMakeFiles/
ITKMetaIO.dir/metaDTITube.cxx.o CMakeFiles/ITKMetaIO.dir/metaEllipse.cxx.o CMa
keFiles/ITKMetaIO.dir/metaFEMObject.cxx.o CMakeFiles/ITKMetaIO.dir/metaForm.cxx.o
CMakeFiles/ITKMetaIO.dir/metaGroup.cxx.o CMakeFiles/ITKMetaIO.dir/
metaGaussian.cxx.o CMakeFiles/ITKMetaIO.dir/metaImage.cxx.o CMakeFiles/ITKMet
aIO.dir/metaImageUtils.cxx.o CMakeFiles/ITKMetaIO.dir/metaLandmark.cxx.o CMakeFiles/
ITKMetaIO.dir/metaLine.cxx.o CMakeFiles/ITKMetaIO.dir/metaMesh.cxx.o CMakeFiles/
ITKMetaIO.dir/metaObject.cxx.o CMakeFiles/ITKMetaIO.dir/metaS
cene.cxx.o CMakeFiles/ITKMetaIO.dir/metaSurface.cxx.o CMakeFiles/ITKMetaIO.dir/
metaTube.cxx.o CMakeFiles/ITKMetaIO.dir/metaTransform.cxx.o CMakeFiles/
ITKMetaIO.dir/metaTubeGraph.cxx.o CMakeFiles/ITKMetaIO.dir/metaVesselTube.c
xx.o /usr/lib/x86_64-linux-gnu/libz.so

Possibly the libz.so pulls in libc??

Any ideas appreciated!

Thanks,
-Steve
P.S. Please CC, not subscribed, thanks!


--------
[1] https://lintian.debian.org/tags/library-not-linked-against-libc.html
Andrey Rakhmatullin
2025-01-26 06:00:01 UTC
Reply
Permalink
Post by Steven Robbins
I've come to realise the ITK build has 15 libraries that lintian flags with
error library-not-linked-against-libc.
https://lintian.debian.org/tags/library-not-linked-against-libc.html[1]
The error description seems straightforward. But how does one solve this? I have to
assume that the linker would by default link with the libc (?), so perhaps the linker
invocation has options that suppress this? What would that be?
Before fixing you need to make sure that those libraries indeed use
symbols from libc (with ldd -r, I guess).
--
WBR, wRAR
Steven Robbins
2025-01-26 07:10:01 UTC
Reply
Permalink
Post by Steven Robbins
I've come to realise the ITK build has 15 libraries that lintian flags with
error library-not-linked-against-libc.
Someone suggested to run ldd -r. Okay, so what does this tell me?

$ ldd -r /lib/x86_64-linux-gnu/libITKColormap-5.4.so
linux-vdso.so.1 (0x00007f1b218a1000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1b21400000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1b21766000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1b2120a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1b218a3000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1b21739000)
Thanks,
-Steve
P.S. Please CC, not subscribed, thanks!
Andrey Rakhmatullin
2025-01-26 11:30:02 UTC
Reply
Permalink
Post by Steven Robbins
Post by Steven Robbins
I've come to realise the ITK build has 15 libraries that lintian flags with
error library-not-linked-against-libc.
Someone suggested to run ldd -r. Okay, so what does this tell me?
$ ldd -r /lib/x86_64-linux-gnu/libITKColormap-5.4.so
linux-vdso.so.1 (0x00007f1b218a1000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1b21400000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1b21766000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1b2120a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1b218a3000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1b21739000)
Oh right, this is not a useful check if the library is linked to anything
that is linked to libc. The correct way is, as lintian says, to check the
symbols imported by the library (with e.g. nm -D) to make sure none of
them are from libc.
Post by Steven Robbins
Thanks,
-Steve
P.S. Please CC, not subscribed, thanks!
Done.
And please use debian-mentors@ for packaging questions next time.
--
WBR, wRAR
Ahmad Khalifa
2025-01-26 11:10:01 UTC
Reply
Permalink
Post by Steven Robbins
I've come to realise the ITK build has 15 libraries that lintian flags with
...
Post by Steven Robbins
The error description seems straightforward.  But how does one solve
this?  I have to assume that the linker would by default link with the
libc (?), so perhaps the linker invocation has options that suppress
this?  What would that be?
You may not need to solve it if it's intentional.
For example, you have a "plugin" style library that only uses functions
from the main library and nothing else.
Post by Steven Robbins
$ objdump -p file.so
...
NEEDED libc.so.6
...
If it doesn't need libc, then lintian error is correct.
You would then sift through the code to see what that library
includes/links against.
Is it intentional that it doesn't need libc? If yes, then override the
error.
--
Regards,
Ahmad
Andrey Rakhmatullin
2025-01-26 11:20:01 UTC
Reply
Permalink
Post by Ahmad Khalifa
The error description seems straightforward.  But how does one solve
this?  I have to assume that the linker would by default link with the
libc (?), so perhaps the linker invocation has options that suppress
this?  What would that be?
You may not need to solve it if it's intentional.
For example, you have a "plugin" style library that only uses functions from
the main library and nothing else.
Yes.
Post by Ahmad Khalifa
$ objdump -p file.so
...
NEEDED libc.so.6
...
No?
Lintian already says there is no "NEEDED libc.so.6", the
question is whether that is an error or not.
--
WBR, wRAR
Ahmad Khalifa
2025-01-26 11:30:02 UTC
Reply
Permalink
Post by Andrey Rakhmatullin
Post by Steven Robbins
$ objdump -p file.so
...
NEEDED libc.so.6
...
No?
Lintian already says there is no "NEEDED libc.so.6", the
question is whether that is an error or not.
I think we're on the same page, I just added an extra step out of caution :)

The lintian error is a great heads-up and it's up to the reader to
decide whether it's a true error to fix or a false-positive to override.
--
Regards,
Ahmad
Jeremy Bícha
2025-01-26 12:50:01 UTC
Reply
Permalink
Post by Ahmad Khalifa
The lintian error is a great heads-up and it's up to the reader to
decide whether it's a true error to fix or a false-positive to override.
I have never seen this Lintian error actually be useful. I think an
error is far too strong for this; I think even a warning is too
strong; maybe info would be ok.

Thank you,
Jeremy Bícha
Ahmad Khalifa
2025-01-26 16:40:02 UTC
Reply
Permalink
Post by Jeremy Bícha
Post by Ahmad Khalifa
The lintian error is a great heads-up and it's up to the reader to
decide whether it's a true error to fix or a false-positive to override.
I have never seen this Lintian error actually be useful. I think an
error is far too strong for this; I think even a warning is too
strong; maybe info would be ok.
Good point. As a heads-up, Info-level is more appropriate or even Pedantic.

Also looking at this partial list of affected packages, 40% have
overridden it - which is pretty high if it were a real error.

https://udd.debian.org/lintian-tag/library-not-linked-against-libc?affected=yes
--
Regards,
Ahmad
Russ Allbery
2025-01-26 17:20:02 UTC
Reply
Permalink
Post by Jeremy Bícha
Post by Ahmad Khalifa
The lintian error is a great heads-up and it's up to the reader to
decide whether it's a true error to fix or a false-positive to override.
I have never seen this Lintian error actually be useful. I think an
error is far too strong for this; I think even a warning is too strong;
maybe info would be ok.
When we introduced it many years ago, it was definitely useful. It's
intended to catch plugin libraries that are linked with the main library
but not with libc explicitly, while still using libc symbols. This case
often works due to the implicit dependency up until it doesn't.

Maybe the tooling is now better in ways that make this much less likely to
happen? And maybe it's more common these days to have plugin libraries
that aren't linked with libc? Back in the day, it was very rare for people
to successfully manage to write code that never called a libc symbol.
--
Russ Allbery (***@debian.org) <https://www.eyrie.org/~eagle/>
Simon McVittie
2025-01-26 17:40:01 UTC
Reply
Permalink
Post by Russ Allbery
maybe it's more common these days to have plugin libraries
that aren't linked with libc? Back in the day, it was very rare for people
to successfully manage to write code that never called a libc symbol.
In ecosystems with a "platform" runtime library like GLib, Qt or even
SDL, and especially when intending to be portable to Windows and macOS
as well as Linux and other Unixy platforms, it's very common to write
code that only ever calls into that runtime library, and never directly
calls libc functions. I think the reason Jeremy is so negative about this
lintian check is that false positives are particularly common in GNOME,
where basically everything is linked to GLib and uses its functions in
preference to going directly to libc.

smcv
Russ Allbery
2025-01-26 17:50:01 UTC
Reply
Permalink
Post by Simon McVittie
maybe it's more common these days to have plugin libraries that aren't
linked with libc? Back in the day, it was very rare for people to
successfully manage to write code that never called a libc symbol.
In ecosystems with a "platform" runtime library like GLib, Qt or even
SDL, and especially when intending to be portable to Windows and macOS
as well as Linux and other Unixy platforms, it's very common to write
code that only ever calls into that runtime library, and never directly
calls libc functions. I think the reason Jeremy is so negative about
this lintian check is that false positives are particularly common in
GNOME, where basically everything is linked to GLib and uses its
functions in preference to going directly to libc.
I suspect what's changed since the introduction of this tag is that use of
as-needed is now much more common and as-needed is removing the libc
dependency. That specific pattern is safe, since the libc dependency would
be introduced if it were needed in the future. Unfortunately, Lintian
currently can't distinguish between that case and the case where the
linker was told not to link against libc at all.

In theory it would be possible to do better in Lintian by scanning the
symbol table to see if the libc dependency is really unneeded. But doing
that sounds at least a little annoying. Downgrading the tag is not really
a fix. That doesn't make the false positives go away; it just encourages
people to ignore more Lintian tags. If people think the problem the tag
was designed to detect is so rare as to warrant downgrading to pedantic, I
would just delete the check entirely.

I have a warning flag set in the back of my head that it's possible for
GCC to introduce calls into libc even if they're not present in the source
(memcpy, maybe?) unless you explicitly tell it to build things in
standalone mode, although maybe I'm misremembering. It's certainly easy to
introduce a libc dependency by writing normal C code and calling some
function that's universally available, including on Windows, without
thinking about it, thus making the state of "not using libc" somewhat
unstable. But problems like that combined with a build system error of
omitting libc entirely are probably much less common than as-needed
removing libc because it's not needed.
--
Russ Allbery (***@debian.org) <https://www.eyrie.org/~eagle/>
Marvin Renich
2025-01-27 13:40:02 UTC
Reply
Permalink
Post by Russ Allbery
In theory it would be possible to do better in Lintian by scanning the
symbol table to see if the libc dependency is really unneeded. But doing
that sounds at least a little annoying.
Annoying to users of lintian or annoying to implement? How so?

I thought of this solution while reading earlier in this thread, and it
seems like the "correct" solution to me. What is wrong with it?

Clearly the current state is a bug in lintian, as so many packages
override this error. And from your description, the test has a
significant purpose that is still needed in the situations it was
intended to catch, even if they are few. The lintian test simply does
not correctly identify _only_ the situations it was supposed to; it
catches many more false positives (now, due to changing programming
practices) than true positives.

...Marvin
Russ Allbery
2025-01-27 18:30:01 UTC
Reply
Permalink
Post by Marvin Renich
Post by Russ Allbery
In theory it would be possible to do better in Lintian by scanning the
symbol table to see if the libc dependency is really unneeded. But
doing that sounds at least a little annoying.
Annoying to users of lintian or annoying to implement? How so?
Annoying to implement because I think the implementation would have to
know what symbols are provided by libc.
Post by Marvin Renich
I thought of this solution while reading earlier in this thread, and it
seems like the "correct" solution to me. What is wrong with it?
Nothing so far as I know. It's just work, and if people don't think that
the problem is likely to occur, maybe the work isn't worth doing and the
tag should just be deleted.
Post by Marvin Renich
Clearly the current state is a bug in lintian, as so many packages
override this error. And from your description, the test has a
significant purpose that is still needed in the situations it was
intended to catch, even if they are few.
Well, I'm not sure I would go that far. It *had* a significant purpose; we
added it originally because it was catching a real problem. But it's
entirely possible that this was an artifact of build systems at the time
and the state of build systems in the archive has gotten much better.
--
Russ Allbery (***@debian.org) <https://www.eyrie.org/~eagle/>
Ahmad Khalifa
2025-01-27 22:50:01 UTC
Reply
Permalink
Post by Russ Allbery
Post by Marvin Renich
Post by Russ Allbery
In theory it would be possible to do better in Lintian by scanning the
symbol table to see if the libc dependency is really unneeded. But
doing that sounds at least a little annoying.
Annoying to users of lintian or annoying to implement? How so?
Annoying to implement because I think the implementation would have to
know what symbols are provided by libc.
To my knowledge objdump will spit out the symbols with (GLIBC_v*)

Having said that, lintian is slow enough as a single thread, I'd vote
for downgrading the tag to Pedantic, but not deleting it.
--
Regards,
Ahmad
Russ Allbery
2025-01-27 23:20:01 UTC
Reply
Permalink
Post by Ahmad Khalifa
Post by Russ Allbery
Annoying to implement because I think the implementation would have to
know what symbols are provided by libc.
To my knowledge objdump will spit out the symbols with (GLIBC_v*)
Oh, if one can reliably detect libc symbols by looking at the symbol
version, that would indeed make it a lot easier. I was assuming that
wasn't necessarily the case, but now I'm not sure why I thought that.
Post by Ahmad Khalifa
Having said that, lintian is slow enough as a single thread, I'd vote for
downgrading the tag to Pedantic, but not deleting it.
So, I guess I'll say this more explicitly: I am opposed to downgrading the
tag to pedantic. If the tag is useful, we should fix it; if it's not
useful, we should delete it.

It's not a pedantic issue with the package. If the error is real, it's
serious, but Lintian's check for the error has a high false positive rate.
That's not what pedantic is for. Pedantic is intended for tags where
Lintian has correctly understood the thing that it is complaining about,
but people do not always agree that thing is worth fixing.

If you really want to keep the tag despite a lot of false positives, the
way to do that would be to make it experimental, but I think experimental
tags are often a dumping ground for things that will never be fixed and it
might be better to just delete it.
--
Russ Allbery (***@debian.org) <https://www.eyrie.org/~eagle/>
Ahmad Khalifa
2025-01-28 18:20:01 UTC
Reply
Permalink
Post by Russ Allbery
Post by Ahmad Khalifa
Having said that, lintian is slow enough as a single thread, I'd vote for
downgrading the tag to Pedantic, but not deleting it.
So, I guess I'll say this more explicitly: I am opposed to downgrading the
tag to pedantic. If the tag is useful, we should fix it; if it's not
useful, we should delete it.
It's not a pedantic issue with the package. If the error is real, it's
serious, but Lintian's check for the error has a high false positive rate.
That's not what pedantic is for. Pedantic is intended for tags where
Lintian has correctly understood the thing that it is complaining about,
but people do not always agree that thing is worth fixing.
If you really want to keep the tag despite a lot of false positives, the
way to do that would be to make it experimental, but I think experimental
tags are often a dumping ground for things that will never be fixed and it
might be better to just delete it.
With your definition, I agree, it's not something to be pedantic about,
it's not a real error.

Here is a quick check I did on random packages from udd [1]:
Picking abseil (300+ overridden), clanlib (9 error) and chicken (300+ error)

# download the relevant debs (sorry formatting)
Post by Russ Allbery
wget https://ftp.debian.org/debian/pool/main/a/abseil/libabsl20230802_20230802.1-4_{amd64,arm64,armel,armhf,i386,mips64el,mipsel,ppc64el,s390x,riscv64}.deb
wget https://ftp.debian.org/debian/pool/main/c/clanlib/libclanapp-1.0t64_1.0~svn3827-11.2+b1_{amd64,arm64,armel,armhf,i386,mips64el,mipsel,ppc64el,s390x,riscv64}.deb
wget https://ftp.debian.org/debian/pool/main/c/chicken/chicken-bin_5.3.0-2_{amd64,arm64,armel,armhf,i386,mips64el,mipsel,ppc64el,s390x,riscv64}.deb
# extract
Post by Russ Allbery
for f in *.deb; do dpkg --extract "$f" ROOT; done
# check for GLIBC symbol without NEEDED libc, libm or loaders
Post by Russ Allbery
for f in ROOT/usr/lib/*-linux-gnu/*.so.* ROOT/var/lib/chicken/11/*.so*; do
(objdump -T "$f" | grep " (GLIBC_[0-9]" > /dev/null) &&
( (objdump -p "$f" | grep -E 'NEEDED *libc.so|NEEDED *libm.so|NEEDED *ld-linux.*.so|NEEDED *ld64.so' > /dev/null) || echo "bad so: $f");
done
Outputs nothing.
Meaning for all libc dynamic symbols, the linker will load one of the
libc libraries.

But reading that, I don't see how the linker could declare a dynamic
GLIBC_ symbol without the related library reference.
In fact, it should choke with "undefined reference" long before
outputting a .so file. Even when compiling with -nolibc. But there is
always a special case somewhere :)
And if the linker wrote broken dynamic sections, I doubt lintian could
find out from just inspecting the .so.

Perhaps the tag really is not relevant anymore or someone has a better test.


1.
https://udd.debian.org/lintian-tag/library-not-linked-against-libc?affected=yes
--
Regards,
Ahmad
Russ Allbery
2025-01-28 20:10:05 UTC
Reply
Permalink
Post by Ahmad Khalifa
But reading that, I don't see how the linker could declare a dynamic
GLIBC_ symbol without the related library reference.
In fact, it should choke with "undefined reference" long before outputting
a .so file. Even when compiling with -nolibc. But there is always a
special case somewhere :)
Historically, it happened with plugins that were built with the Libtool
-module flag or the underlying equivalents, which allows creation of a
shared library module with undefined references. This is (or at least was)
normal behavior for modules meant to be opened with dlopen; the symbols
are resolved at dlopen time from the program that is importing the module.

This is desired behavior when the symbols are coming from the program, but
it is (or at least was) easy to accidentally leave libc symbols undefined
as well, in which case they too are resolved from the main executable at
dlopen time. My recollection (it's been a *lot* of years so I'm hoping I'm
getting this right) is that this interfered with proper symbol versioning
and could cause the symbols to be resolved weirdly in a way that could
cause serious bugs.
--
Russ Allbery (***@debian.org) <https://www.eyrie.org/~eagle/>
Sam Hartman
2025-01-28 22:30:01 UTC
Reply
Permalink
Russ> recollection (it's been a *lot* of years so I'm hoping I'm
Russ> getting this right) is that this interfered with proper symbol
Russ> versioning and could cause the symbols to be resolved weirdly
Russ> in a way that could cause serious bugs.

Yeah, and so the symbol versions would not be present, and so I think
we're back to needing to know what symbols are from libc6.
A better error if we knew how to generate it efficiently would be using
a libc symbol without a symbol version.
Russ Allbery
2025-01-29 00:10:01 UTC
Reply
Permalink
Post by Sam Hartman
Russ> recollection (it's been a *lot* of years so I'm hoping I'm
Russ> getting this right) is that this interfered with proper
Russ> symbol versioning and could cause the symbols to be resolved
Russ> weirdly in a way that could cause serious bugs.
Yeah, and so the symbol versions would not be present, and so I think
we're back to needing to know what symbols are from libc6. A better
error if we knew how to generate it efficiently would be using a libc
symbol without a symbol version.
dlopen() itself is versioned to libc on the calling object, but there is
no record of what is passed to it aside from a floating string somewhere
in the ro section. Unless you parse the source or disassemble the .so,
you can't find out what is being called.
In other words, lintian can't find out if the library loads printf() for
example. But you can test it to see if it works correctly :)
I think we may still not be on quite the same page about what I understand
the problem to be, and what the Lintian check is trying to detect. The
Lintian check is not aimed at the binary doing the dlopen() call. It's
aimed at the *.so file that is the target of the dlopen() call.

Warning: lots of simplification and hand-waving here. This is not fully
accurate to how things work, but is hopefully close enough to get the idea
across.

When shared code is loaded through dlopen(), its declared library
dependencies are resolved in a similar manner to when dynamic libraries
are loaded. Then, once those symbols are resolved, any remaining
unresolved symbols are resolved from the binary that called dlopen().

Historically we have relied on this behavior in, for example, Perl XS
modules which have unresolved references to the Perl interpreter symbols,
which can be resolved either from /usr/bin/perl (in the normal case) or
from libperl.so.5.40 (in the embedded Perl case). In other words, those
symbols are left *intentionally* unresolved because we do not want to
create a dependency on libperl because we do not want to load libperl into
/usr/bin/perl; we want the module symbols to be resolved against
/usr/bin/perl. (There are various reasons for this that mostly come down
to performance.)

The problem is that once you start linking modules using the flags that
allow them to leave the Perl symbols unresolved, you run the risk of also
leaving *other* shared library symbols unresolved, including,
specifically, libc.

Now, you may think that this is not really a problem, because the main
binary has a dependency on libc and thus those symbols will be resolved at
dlopen() time just like the Perl symbols. The problem is that, at least as
I remember this, the symbol version resolution happens at link time. The
binary only knows that it needs ***@GLIBC_2.2.5 because it was linked
with libc. If it's *not* linked with libc, the unresolved symbol will just
be strerror without the version. That in turn means, I believe, that it
resolves to the latest version of strerror found in the process space,
which can be the wrong version of strerror if the ABI has changed. (It
hasn't for strerror, but it has for some other things.)

You can detect this from readelf on the module *.so file, but you can't
detect this by looking for the @GLIBC symbol versions because in the
unlinked case the symbol versioning doesn't happen. You have to look for
bare undefined strerror references with no symbol version, which would
indeed represent a bug. But you *don't* want to alert on the unresolved
Perl symbols, because those are intentional. So that's how we get back to
having to know which symbols are found in libc and therefore should have
attached symbol versions.
--
Russ Allbery (***@debian.org) <https://www.eyrie.org/~eagle/>
Russ Allbery
2025-01-30 02:30:01 UTC
Reply
Permalink
Instead, lintian should alert that some symbols are "unversioned".
The problem is that unversioned symbols are often correct. For one, not
every shared library uses symbol versioning; we may want them all to use
symbol versioning, and certainly way more of them do today, but I don't
think it's universal.

But, more critically, the Perl XS case relies on unversioned symbols. We
have a use case that uses unresolved symbols, which therefore aren't
versioned. And even if we decided to handle Perl XS modules a different
way, I believe this pattern occurs elsewhere when the symbols in the
loaded module need to be resolved against the executable that loads that
module. I believe those symbols basically *can't* be versioned, at least
in the normal way.
Whether you can detect this or not, it would probably be a new tag
anyway. But being practical, the stability of libc nowadays is much
higher and it's better to just have lintian-is-always-right!!
I don't think this problem is about the stability of libc. I don't think
anything relevant has changed there; libc does change ABIs in a way that
isn't backward compatible, because that's exactly what symbol versioning
was designed to allow it to do. Older binaries use the older symbol
version and get the old behavior and everything continues to work.

Lintian is trying to ensure that the libc symbols in modules are correctly
versioned and wired to the correct libc symbols. That's hard to check
correctly, but will happen automatically if the module is linked with
libc, which is why Lintian is instead detecting a proxy for the problem
that it's trying to detect and complaining about modules not linked with
libc. The problem is that not linking with libc if one doesn't use any of
its symbols is both fine and more common these days due to increased use
of --as-needed.

The bug that Lintian is trying to detect is the presence of unversioned
unresolved symbols in a shared library or module when the underlying
symbol to which that symbol should resolve is, in fact, versioned. The
problem is that the information required to diagnose that problem is
difficult for Lintian to acquire.
In my short experience running lintian, it has been right 99% of the
time, so this feels like a bug.
Oh, sure, I completely agree that the false positives are a bug.
--
Russ Allbery (***@debian.org) <https://www.eyrie.org/~eagle/>
David Kalnischkies
2025-01-26 12:00:02 UTC
Reply
Permalink
Hi,
Post by Steven Robbins
/usr/bin/c++ -fPIC -g -O2 -ffile-prefix-map=/home/steve/Packages/insighttoolkit/build-area/
insighttoolkit5-5.4.0=. -fstack-protector-strong -fstack-clash-protection -Wformat -
Werror=format-security -fcf-protection -Wdate-time
-D_FORTIFY_SOURCE=2 -I/usr/include/nifti -g1 -mtune=generic -march=corei7 -Wall -
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Post by Steven Robbins
Wcast-align -Wdisabled-optimization -Wextra -Wformat=2 -Winvalid-pch -Wno-format-
nonliteral -Wpointer-arith -Wshadow -Wunused -Wwrite-strings
-Wno-strict-overflow -Wno-deprecated -Wno-invalid-offsetof -Woverloaded-virtual -Wctad-
maybe-unsupported -Wstrict-null-sentinel -fno-sized-deallocation -msse2 -Wl,--
^^^^^^
Post by Steven Robbins
dependency-file=CMakeFiles/ITKColormap.dir/link.d -Wl,-z,re
lro -shared -Wl,-soname,libITKColormap-5.4.so.1 -o ../../../../lib/x86_64-linux-gnu/
libITKColormap-5.4.so.1 CMakeFiles/ITKColormap.dir/
itkScalarToRGBColormapImageFilter.cxx.o
You are building the package only for amd64, but even for that corei7
might be a bit much to ask for.

You and/or upstream might be interested in some of the tipps and tricks
from https://wiki.debian.org/InstructionSelection to use more/less
instructions as needed than the baseline.

On a sidenote: I would have expected this thread on d-mentors.


Best regards

David Kalnischkies
Loading...