Re: Should /usr/include/fts.h adding fts_dirfd and __fts_reserved[3] to FTSENT (a.k.a. struct _ftsent) require a change from libc.so.7 to .8 because of some resulting binary incompatibilities?
Date: Sun, 27 Sep 2026 20:33:37 UTC
On Sun, Sep 27, 2026 at 01:19:15PM -0700, Mark Millard wrote: > On 9/24/26 20:06, Konstantin Belousov wrote: > > On Thu, Sep 24, 2026 at 06:57:04PM -0700, Mark Millard wrote: > >> On 9/24/26 17:16, Mark Millard wrote: > >>> On 9/24/26 16:40, Warner Losh wrote: > >>>> No. Symbol versioning. > >>> > >>> jevents has no symbol versioning for its own, internal implementation of > >>> a function it decided to name fts_compare as far as I can tell. That > >>> same fts_compare implementation is passed in everywhere that the same > >>> libc.so.7 naming is in use and then is called no matter what, > >>> independent of which fts.h vintage it was built with. > >>> > >>> If symbol versioning applies here, how does it work? > >>> > >>> (Why I ended up with the mix of an older jevents with a post-change > >>> environment is a separate issue and is my fault. But nothing rejected or > >>> fixed the combination. libc.so.8 vs. libc.so.7 would have rejected.) > >> > >> Your note caused me to somewhat better isolate the structure of the mix: > >> > >> The kernel is updated to : 1600026 > >> The world is updating from: 1600019 (so: old fts.h) > >> The world is updating to : 1600026 (or trying to) > >> > >> # readelf -a > >> /usr/obj/BUILDs/main-CA76-dbg-clang/usr/main-src/arm64.aarch64/lib/libc/libc.so.7 > >> | grep fts_open@ > >> 0000000000243d10 00000c7a00000402 R_AARCH64_JUMP_SLOT > >> 00000000000c0c40 fts_open@@FBSD_1.9 + 0 > >> 3194: 00000000000c0c40 128 FUNC GLOBAL DEFAULT 14 > >> fts_open@@FBSD_1.9 > >> 3195: 00000000000c29c0 1016 FUNC GLOBAL DEFAULT 14 > >> fts_open@FBSD_1.0 > >> 3196: 00000000000c4260 924 FUNC GLOBAL DEFAULT 14 > >> fts_open@FBSD_1.1 > >> 3197: 00000000000c5b60 124 FUNC GLOBAL DEFAULT 14 > >> fts_open@FBSD_1.5 > >> > >> (Associated with building from modern 1600026 source at the time.) > >> > >> jevents got: > >> > >> # readelf -a > >> /usr/obj/BUILDs/main-CA76-dbg-clang/usr/main-src/arm64.aarch64/lib/libpmc/pmu-events/jevents > >> | grep fts_open@ > >> 0000000000037680 0000001300000402 R_AARCH64_JUMP_SLOT > >> 0000000000000000 fts_open@FBSD_1.9 + 0 > >> 19: 0000000000000000 0 FUNC GLOBAL DEFAULT UND > >> fts_open@FBSD_1.9 > >> > >> > >> But, as a build-tool, jevents was built with /usr/include/fts.h instead > >> of with the /usr/main-src/ tree that I use for the build if the update. > >> (/usr/src/ is from pkgbase.): > >> > >> # diff -u /usr/include/fts.h /usr/main-src/include/fts.h > >> --- /usr/include/fts.h 2025-05-11 07:29:42.791259000 -0700 > >> +++ /usr/main-src/include/fts.h 2026-09-18 16:13:35.766402000 -0700 > >> @@ -1,4 +1,4 @@ > >> -/*- > >> +/* > >> * SPDX-License-Identifier: BSD-3-Clause > >> * > >> * Copyright (c) 1989, 1993 > >> @@ -92,6 +92,8 @@ > >> char *fts_path; /* root path */ > >> int fts_errno; /* errno for this node */ > >> int fts_symfd; /* fd for symlink */ > >> + int fts_dirfd; /* fd for this directory, if a > >> directory */ > >> + int __fts_reserved[3]; /* reserved for future use */ > >> __size_t fts_pathlen; /* strlen(fts_path) */ > >> __size_t fts_namelen; /* strlen(fts_name) */ > >> > >> @@ -146,6 +148,8 @@ > >> #define fts_get_stream(ftsent) ((ftsent)->fts_fts) > >> FTS *fts_open(char * const *, int, > >> int (*)(const FTSENT * const *, const FTSENT * const *)); > >> +FTS *fts_openat(int, char * const *, int, > >> + int (*)(const FTSENT * const *, const FTSENT * const *)); > >> #ifdef __BLOCKS__ > >> FTS *fts_open_b(char * const *, int, > >> int (^)(const FTSENT * const *, const FTSENT * const *)); > >> > >> Thus the result was a jevents using: > >> > >> ) the old /usr/include/fts.h header of its "host" environment > >> but also: > >> ) the new symbol version fts_open@@FBSD_1.9 was used. > >> > >> Nothing rejected the bad combination (other than a later SIGSEGV). > > > > Right, if it is the case, then the ABI mismatch is unavoidable. > > By itself, this sounds like a serious bug in our build system. > > > >> > >> I do not see how /usr/include/fts.h file content would end up somehow in > >> control over fts_open@@FBSD_1.5 vs. fts_open@@FBSD_1.9 being used for > >> the likes of the jevents build. > > > > Include files provide a part of the ABI, which is used by compiler. > > In particular, include files define the layout of C structures. > > > > Shared libraries provide another part, giving the (default) versions to the > > symbols referenced by the final object. Layout of the parameters to > > the specific version of the function must match to what headers used > > at compile time defined. > > > > Mixing these parts across ABI changes cannot work. > > > > > > I think I've identified what went wrong in the history of trying this > update in my context: a separate installworld race issue (-j used) lead > to an initial partial update of the chroot/jail tree, where: > > ) libc.so.7 updated before that installworld failed. > > ) /usr/include/fts.h did not. > (Would have installed after the installworld failure point.) > > So later activity then had the incoherent mix without me identifying it > at the time. For this sequencing, libc.so.8 use would not have helped. Just for the posteriority: libc.so.8 will never happen. At least now we do not have any reason to believe otherwise. > > (Via avoiding -j use for installworld I've gotten all my chroot/jail > tree personal builds to avoid the race.) > > -- > === > Mark Millard > marklmi at yahoo.com