Bug 272642 - security/keepassxc: Undefined symbol
Summary: security/keepassxc: Undefined symbol
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Some People
Assignee: Li-Wen Hsu
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-07-21 16:43 UTC by Daniel Ebdrup Jensen
Modified: 2024-02-27 03:15 UTC (History)
8 users (show)

See Also:
bugzilla: maintainer-feedback? (lwhsu)


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Ebdrup Jensen freebsd_committer freebsd_triage 2023-07-21 16:43:01 UTC
On a freshly upgraded 14-CURRENT with packages built on Thu, 20 Jul 2023 21:38:27 GMT according to the last-modified date of packagesite.txz according to curl, both keepassxc and keepassxc-cli return `Undefined symbol "_ZTVNSt3__13pmr25monotonic_buffer_resourceE"`.

uname:
FreeBSD geroi 14.0-CURRENT FreeBSD 14.0-CURRENT amd64 1400093 #10 build-n264265-47d0c1fe7d32: Fri Jul 21 17:20:31 CEST 2023     root@geroi:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64

I don't think it's an issue that'll only affect me, because I used `pkg upgrade -f`.
Comment 1 Ed Maste freebsd_committer freebsd_triage 2023-08-07 03:36:31 UTC
I have an issue with the same symbol, from mesa-dri-22.3.7_2:

[185255.231] (EE) AIGLX error: dlopen of /usr/local/lib/dri/swrast_dri.so failed
 (/usr/local/lib/dri/swrast_dri.so: Undefined symbol "_ZTVNSt3__13pmr25monotonic
_buffer_resourceE")

demangled symbol is "vtable for std::__1::pmr::monotonic_buffer_resource"

See also https://github.com/llvm/llvm-project/commit/243da90ea5357c1ca324f714ea4813dc9029af27
Comment 2 Ed Maste freebsd_committer freebsd_triage 2023-08-07 13:40:02 UTC
In my case the issue is I hadn't successfully installed (entire) world. My error  is not reproducible after installworld.
Comment 3 mmatalka 2023-10-03 23:52:26 UTC
I've run into this issue as well.  I compiled and installed world today.  As far as I know I have completely installed world.
Comment 4 mmatalka 2023-10-03 23:53:30 UTC
Specific error:

ld-elf.so.1: /usr/local/lib/qt5/libQt5Widgets.so.5: Undefined symbol "_ZTVNSt3__13pmr25monotonic_buffer_resourceE"
Comment 5 Alan Somers freebsd_committer freebsd_triage 2023-10-09 00:45:41 UTC
I am also seeing this error after using freebsd-update to upgrade to 14.0-BETA4.  Reinstalling world as emaste suggested did not help.
Comment 6 Dimitry Andric freebsd_committer freebsd_triage 2023-10-10 18:54:22 UTC
I think either mesa or qt are doing something strange with dlopen() here, but it is still unclear what.

Can you all please try to compile the following small C++ program:

======================================================================
#include <memory_resource>

int main(void)
{
  std::pmr::monotonic_buffer_resource mbr;
  return 0;
}
======================================================================

with:

c++ -std=c++17 test-mbr.cpp -o test-mbr

and then see if it runs? This should contain a reference to the monotonic_buffer_resource vtable.
Comment 7 Alan Somers freebsd_committer freebsd_triage 2023-10-10 19:40:28 UTC
(In reply to Dimitry Andric from comment #6)
Your test program works for me.
Comment 8 Mark Millard 2023-10-10 20:47:24 UTC
(In reply to Dimitry Andric from comment #6)

qt5/qt6 do not need to be involved. A much simpler
context reproduced the problem. (Not via my context,
however.)

I had suggested an experiment with the example program at:

https://en.cppreference.com/w/cpp/memory/monotonic_buffer_resource

that does not involve dlopen or the like in the source but that
does actually use monotonic_buffer_resource (for timing
comparisons to alternatives). I suggested using:

# c++ -std=c++17 -pedantic -O2 monotonic_buffer_resource.cpp
# ./a.out

https://lists.freebsd.org/archives/freebsd-stable/2023-October/001534.html

reported for a person with the qt* problem already known to be
at issue in their environment:

QUOTE
The program compiles & links fine, but then also fails to run:

ld-elf.so.1: Undefined symbol "_ZTVNSt3__13pmr25monotonic_buffer_resourceE" referenced from COPY relocation in /usr/home/jbo/junk/a.out
END QUOTE

It looks like the monotonic_buffer_resource.cpp vs. qt* tests
predict each other's results, despite how little is in common.

(I've never seen the problem myself. I was just making investigative
suggestions. I do not have qt5/qt6 in use active in my environment.
I've noly tried the simpler test, and only on aarch64.)

I note this in part because no one replied with information about
your even simpler test case.
Comment 9 Mark Millard 2023-10-10 20:51:20 UTC
(In reply to Mark Millard from comment #8)

Make that last text in #7 be:

I note this in part because no one other than Alan replied with
information about your even simpler test case --and the result
was different than Alan's in that execution failed for the
somewhat more complicated example even though the link did not
complain.
Comment 10 Joel Bodenmann freebsd_committer freebsd_triage 2023-10-10 21:16:37 UTC
Mark already linked the corresponding ML thread but I'm experiencing this same issue on a stable/13 machine after upgrading from one commit to another one. I have rebuild & reinstalled world (and kernel, but that shouldn't matter) several times now using different commits from the span of the last week. The problem persists.

As Mark pointed out this definitely doesn't seem to be a "Qt related issue".

(In reply to Mark Millard from comment #8)
Qt just links to the same symbol internally as the minimal test case. Hence the same symptoms appear.
Comment 11 Mark Millard 2023-10-10 21:44:10 UTC
(In reply to Joel Bodenmann from comment #10)
(In reply to Alan Somers from comment #7)

Joel: You might want  to try the simpler test program in
comment #6 . Alan reported that it did not fail for him.
If the two examples behave differently in some context,
that may be significant.

Alan: You might want to try the larger test program from:

https://en.cppreference.com/w/cpp/memory/monotonic_buffer_resource

If the two examples behave differently in some context,
that may be significant.
Comment 12 Dimitry Andric freebsd_committer freebsd_triage 2023-10-10 21:47:14 UTC
Well, I can compile both the minimal example and the cppreference example here, and they both run without any issues. That said, I am on 15-CURRENT, with a llvm (and libc++) 17.0.2 update, so it could be that something was changed in libc++ in the mean time.

Note that upstream libc++ moved the destructor into the shared library here:
<https://github.com/llvm/llvm-project/commit/57215eda64d089cecdd866026fd8a80db5dd1032>:
>  [libc++][PMR] Move the pmr::memory_resource destructor into the dylib
> 
> This avoids emitting the VTable of `pmr::memory_resource` in every TU.

It could that we're getting some weird mix of virtual tables in both the main executable *and* the library:

% nm --extern --defined-only test-mbr | c++filt | grep std::__1::pmr::memory_resource
0000000000201d90 W std::__1::pmr::memory_resource::memory_resource()
00000000002031b8 B vtable for std::__1::pmr::memory_resource

So this has the constructor as a weak symbol, the vtable in BSS.

% nm --dynamic --defined-only /usr/lib/libc++.so.1 | c++filt | grep std::__1::pmr::memory_resource
00000000000eb540 W std::__1::pmr::__null_memory_resource_imp::do_is_equal(std::__1::pmr::memory_resource const&) const
00000000000eafd0 T std::__1::pmr::synchronized_pool_resource::do_is_equal(std::__1::pmr::memory_resource const&) const
00000000000eb4f0 W std::__1::pmr::__new_delete_memory_resource_imp::do_is_equal(std::__1::pmr::memory_resource const&) const
00000000000ea920 T std::__1::pmr::memory_resource::~memory_resource()
00000000000eb500 T std::__1::pmr::memory_resource::~memory_resource()
00000000000eb500 T std::__1::pmr::memory_resource::~memory_resource()
00000000000ea960 T std::__1::pmr::set_default_resource(std::__1::pmr::memory_resource*)
00000000000ea9e0 T std::__1::pmr::unsynchronized_pool_resource::__adhoc_pool::__do_allocate(std::__1::pmr::memory_resource*, unsigned long, unsigned long)
00000000000ea980 T std::__1::pmr::unsynchronized_pool_resource::__adhoc_pool::__release_ptr(std::__1::pmr::memory_resource*)
00000000000eaa50 T std::__1::pmr::unsynchronized_pool_resource::__adhoc_pool::__do_deallocate(std::__1::pmr::memory_resource*, void*, unsigned long, unsigned long)
00000000000eab20 T std::__1::pmr::unsynchronized_pool_resource::unsynchronized_pool_resource(std::__1::pmr::pool_options const&, std::__1::pmr::memory_resource*)
00000000000eab20 T std::__1::pmr::unsynchronized_pool_resource::unsynchronized_pool_resource(std::__1::pmr::pool_options const&, std::__1::pmr::memory_resource*)
0000000000101860 D typeinfo for std::__1::pmr::memory_resource
000000000004b3d7 R typeinfo name for std::__1::pmr::memory_resource
0000000000101888 D vtable for std::__1::pmr::memory_resource

Here, the destructor is in the text segment, and the vtable is in the initialized data segment.

However, on my systems, the program runs without any issue.
Comment 13 Joel Bodenmann freebsd_committer freebsd_triage 2023-10-10 21:49:55 UTC
(In reply to Mark Millard from comment #11)
That one doesn't work for me either. Fails the same way as the previous example we tried (the example from cppreference). It compiles and links fine, but then doesn't find the symbol upon execution:

➜  test2 cat test-mbr.cpp 
#include <memory_resource>

int main(void)
{
  std::pmr::monotonic_buffer_resource mbr;
  return 0;
}
➜  test2 c++ -std=c++17 test-mbr.cpp -o test-mbr

➜  test2 ./test-mbr 
ld-elf.so.1: Undefined symbol "_ZTVNSt3__13pmr25monotonic_buffer_resourceE" referenced from COPY relocation in /usr/home/jbo/test2/test-mbr

For future references, here's some system info:

stable/13 on c11f71789d7d8f741243c21add8d7c5f0ecea03e

# uname -apKU
FreeBSD beefy02 13.2-STABLE FreeBSD 13.2-STABLE stable/13-n256520-c11f71789d7d GENERIC amd64 amd64 1302508 1302508

# freebsd-version -kru
13.2-STABLE
13.2-STABLE
13.2-STABLE

# c++ --version
FreeBSD clang version 16.0.6 (https://github.com/llvm/llvm-project.git llvmorg-16.0.6-0-g7cbf1a259152)
Target: x86_64-unknown-freebsd13.2
Thread model: posix
InstalledDir: /usr/bin
Comment 14 Mark Millard 2023-10-10 21:52:08 UTC
(In reply to Dimitry Andric from comment #6)
(In reply to Joel Bodenmann from comment #10)

I forgot to report that Joel's context was 13.2-STABLE .
Also, using teh recent 13.2-STABLE for an aarch64, I
did not manage to reproduce the problem.

The issue is not limited to 14.0+ .
The issue might not happen for aarch64.
It may be that the problem has only been observed on amd64.
Comment 15 Alan Somers freebsd_committer freebsd_triage 2023-10-10 21:56:19 UTC
The more complicated example from https://en.cppreference.com/w/cpp/memory/monotonic_buffer_resource also works for me on 14.0-BETA4.  But QT5 still doesn't.
Comment 16 Joel Bodenmann freebsd_committer freebsd_triage 2023-10-10 22:00:25 UTC
I'm playing with the thought of upgrading my affected machine to stable/14 but really not sure what to expect given that we seem to have a wide spread of results on this so far.
Comment 17 Alan Somers freebsd_committer freebsd_triage 2023-10-10 22:06:54 UTC
The reason why the problem doesn't manifest on 13.2-RELEASE, but does on stable/13 and later is because of freebsd-src commit e3b557809604d036af6e00c60f012c2025b59a5e.  releng/13.2 is missing that one.  That's the commit that defines __cpp_lib_memory_resource , and without that macro defined qt5-widgets won't attempt to use monotonic_buffer_resource.
Comment 18 Mark Millard 2023-10-10 22:18:40 UTC
(In reply to Dimitry Andric from comment #12)

Looking at all the material so far, it does not look
like anyone has explicitly indicated a main [so: 15]
instance of the problem.

a 13.2-STABLE and various 14.0's are all I've noticed
in the reports.

(I will note that having devel/binutils@NAME installed
with NAME being for the same platform that is running does
odd things to which linker is used: the one found down
under /usr/local/... is found and used instead of the
system linker, last I checked. I stopped installing
such binutils because of the sometimes resulting link
failures. As I remember, an explicit command line
indication that specfied either bfd or lld was to be used
avoided the odd selection of the linker in /usr/local/... .)
Comment 19 Tomoaki AOKI 2023-10-10 22:19:56 UTC
Not the same, but does Bug 268652 "Qt5: Some apps fails to start after upgrading to 5.15.8" be of any hint?
I'venever bitten by keepassxc both on current (main) and on stable/14.
Each of them are source-updated amd64.
Comment 20 Joel Bodenmann freebsd_committer freebsd_triage 2023-10-10 23:53:04 UTC
(In reply to Tomoaki AOKI from comment #19)

I briefly looked over the PR you linked and I don't think that this is related. The issue we're seeing here appears to be a missing symbol in  base libc++.
Comment 21 Mark Millard 2023-10-11 02:37:00 UTC
(In reply to Joel Bodenmann from comment #20)

I and others have shown example commands that report on the
status of the symbol in various files. Have you someplace
reported the analogous output for those files in your
problematical environment?

Dimitry's comment 12 may have the better example commands.
Comment 22 Alan Somers freebsd_committer freebsd_triage 2023-10-11 02:52:00 UTC
I tried running the commands from comment 12 and discovered a new clue:

==== COMMANDS ====

On a 15.0-CURRENT machine where keepassxc-cli works:

> file /usr/lib/libc++.so.1
/usr/lib/libc++.so.1: cannot open `/usr/lib/libc++.so.1' (No such file or directory)

> file /lib/libc++.so.1
/lib/libc++.so.1: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 15.0 (1500000), stripped

On a 14.0-BETA3 machine where keepassxc-cli works:

> file /usr/lib/libc++.so.1
/usr/lib/libc++.so.1: cannot open `/usr/lib/libc++.so.1' (No such file or directory)

> file /lib/libc++.so.1
/lib/libc++.so.1: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 14.0 (1400097), stripped

On a 13.2-RELEASE machine where keepassxc-cli works:

> file /usr/lib/libc++.so.1
/usr/lib/libc++.so.1: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 13.2, stripped

> file /lib/libc++.so.1
/lib/libc++.so.1: cannot open `/lib/libc++.so.1' (No such file or directory)

On my 14.0-BETA4 machine where keepassxc-cli fails:

> file /lib/libc++.so.1
/lib/libc++.so.1: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 14.0 (1400097), stripped

> file /usr/lib/libc++.so.1
/usr/lib/libc++.so.1: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 13.2, stripped

And, ... removing /usr/lib/libc++.so.1 on the 14.0-BETA4 machine fixes the problem.

=== ANALYSIS ====
So it seems like in FreeBSD 13, the file was /usr/lib/libc++.so.1 , but in 14 it moved from /usr/lib to /lib.  But something in the upgrade process causes the file to get left behind in /usr/lib, on _some_ machines but not others.  The upgrade path for the offending machine was 13.2-RELEASE -> 14.0-BETA4 and for the working one 13.2-RELEASE -> 14.0-BETA3 .  So the bug may have been introduced in -BETA4.  But maybe not, because both of those machines have long previous upgrade histories, and who knows what else in their environments could've screwed things up.
Comment 23 Dimitry Andric freebsd_committer freebsd_triage 2023-10-11 06:03:30 UTC
Yeah, leaving the old /usr/lib/libc++.so.1 would be a possible cause for this problem. Depending on how applications load their shared libraries, loading the wrong file could happen.

libc++.so.1 got moved from /usr/lib to /lib in https://cgit.freebsd.org/src/commit/?id=6b1c5775d1c2, but this only applies to main and stable/14, not stable/13.

Note that a user still has to run "make delete-old-libs" after installworld, to remove the old library!
Comment 24 Tomoaki AOKI 2023-10-11 09:13:41 UTC
(In reply to Joel Bodenmann from comment #20)

Yes, it would not be directly related as the failure mode is different.
Why I've linked the PR was because Qt5 (maybe Qt6, too?) often entangles dynamically linked objects. So any of successful solutions (differs from time to time, unfortunately) could be diverted here.
Comment 25 Tomoaki AOKI 2023-10-11 09:23:12 UTC
(In reply to Dimitry Andric from comment #23)

Unfortunately, I could not find any description on neither /usr/src/UPDATING nor /usr/src/RELNOTES. So this could be a pitfall for many others who, for some reason, cannot run `make delete-old-libs`.

On updating stable/13 to stable/14, I've created the script below, check for leftovers (could not rebuilt on stable/14), confirmed all leftovers are marked as BROKEN or no longerneeded, deinstalled them and finally did `make delete-old-libs`.

#!/bin/sh

CURVERS=14
TMPLIST=/tmp/pkglist

pkg version -o | cut -f 1 -w > ${TMPLIST}

cat ${TMPLIST} | while read PACKAGE
do
  ARCH=`pkg query %q ${PACKAGE}`
  if [ ${CURVERS} != `echo ${ARCH} | cut -f 2 -d :` ]
  then
    echo Port ${PACKAGE} : ${ARCH}
  fi
done
Comment 26 Mark Millard 2023-10-11 12:33:22 UTC
(In reply to Dimitry Andric from comment #23)

QUOTE
Note that a user still has to run "make delete-old-libs" after installworld, to remove the old library!
END QUOTE

In general that can be a problem when one must first rebuild
ports or such to depend only on newer, incompatible system
libraries. There is a reason delete-old and delete-old-libs
are separate: so delete-old-libs can be delayed.

The old /usr/lib/libc++.so.1 could mess up the procedure
for getting ready to do delete-old-libs .
Comment 27 Alan Somers freebsd_committer freebsd_triage 2023-10-11 13:00:50 UTC
(In reply to Dimitry Andric from comment #23)
"make delete-old-libs" would probably fix this bug.  But I upgraded with freebsd-update, so I shouldn't have to do that.  I think this is probably a bug in freebsd-update.
Comment 28 Dimitry Andric freebsd_committer freebsd_triage 2023-10-11 13:35:07 UTC
(In reply to Alan Somers from comment #27)
Just to be 100% sure, can you confirm (and other too) that in your situation, you indeed have *both* /lib/libc++.so.1 and /usr/lib/libc++.so.1 (the latter one being the older)?
Comment 29 Ed Maste freebsd_committer freebsd_triage 2023-10-11 13:59:15 UTC
(In reply to Alan Somers from comment #27)
I wasn't able to reproduce this using freebsd-update. I started with a 13.2 (p2) VM image on vultr.com, freebsd-updated it to p4, then ran:

# freebsd-update -r 14.0-BETA5 upgrade
# freebsd-update install
# shutdown -r now

at this point the kernel is updated to 14.0-BETA5. Then,

# freebsd-update install

freebsd-update reports:
Completing this upgrade requires removing old shared object files.
Please rebuild all installed 3rd party software (e.g., programs
installed from the ports tree) and then run "/usr/sbin/freebsd-update install"
again to finish installing updates.

And indeed, we have two copies of libc++.so.1:
# ls -l /lib/libc++.so* /usr/lib/libc++.so*
-r--r--r--  1 root wheel 1055856 Oct 11 13:49 /lib/libc++.so.1
-r--r--r--  1 root wheel      48 Oct 11 13:50 /usr/lib/libc++.so
-r--r--r--  1 root wheel 1029112 Apr  7  2023 /usr/lib/libc++.so.1

Running again (as required) removes the old one:
# freebsd-update install
# ls -l /lib/libc++.so* /usr/lib/libc++.so*
-r--r--r--  1 root wheel 1055856 Oct 11 13:49 /lib/libc++.so.1
-r--r--r--  1 root wheel      48 Oct 11 13:50 /usr/lib/libc++.so
Comment 30 Ed Maste freebsd_committer freebsd_triage 2023-10-11 14:07:09 UTC
And then running it again confirms there is nothing to do:

# freebsd-update install
No updates are available to install.
Run '/usr/sbin/freebsd-update fetch' first.
Comment 31 Alan Somers freebsd_committer freebsd_triage 2023-10-11 14:48:39 UTC
Dmitry, yes I can confirm that.

Ed, I use a slightly different upgrade procedure.  I create a new BE, install everything there, and then reboot.  That way I only need to reboot once.  And since I use sudo, I can see exactly what commands I ran from /var/log/auth.log:

/sbin/bectl create 14.0-BETA4
/sbin/bectl mount 14.0-BETA4
/usr/sbin/freebsd-update -b /tmp/be_mount.Tu46 -d /tmp/be_mount.Tu46/var/db/freebsd-update upgrade -r 14.0-BETA4
/usr/sbin/freebsd-update -b /tmp/be_mount.Tu46 -d /tmp/be_mount.Tu46/var/db/freebsd-update install
/usr/sbin/freebsd-update -b /tmp/be_mount.Tu46 -d /tmp/be_mount.Tu46/var/db/freebsd-update install
/bin/rm /tmp/be_mount.Tu46//usr/include/c++/v1/__string
/bin/mkdir /tmp/be_mount.Tu46//usr/include/c++/v1/__string
/usr/sbin/freebsd-update -b /tmp/be_mount.Tu46 -d /tmp/be_mount.Tu46/var/db/freebsd-update install
/usr/sbin/pkg -c /tmp/be_mount.Tu46 update
/usr/sbin/pkg -c /tmp/be_mount.Tu46 upgrade
/sbin/bectl activate 14.0-BETA4
/sbin/poweroff

So I did run "freebsd-update install" the expected 3 times, but in slightly the wrong order; I should've upgraded packages before the third "freebsd-update install".  Still, I don't see how that mistake could've caused this problem.  And when I run it now, I get the usual "No updates are available to install" error.
Comment 32 Ed Maste freebsd_committer freebsd_triage 2023-10-11 15:31:56 UTC
(In reply to Alan Somers from comment #31)
> So I did run "freebsd-update install" the expected 3 times, but in slightly the wrong
> order; I should've upgraded packages before the third "freebsd-update install".  Still,
> I don't see how that mistake could've caused this problem.  And when I run it now, I get
> the usual "No updates are available to install" error.

I also don't see how that order would cause this issue. Can you still access the old boot environment to try reproducing the issue? Running under script(1) and viewing the full lists of files that will be removed/added/modified.

One potential way I could imagine this happening is say an incomplete 13.2 -> 14.0-BETA3 (i.e., missing the 3rd step), followed by a 14.0-BETA3 -> 14.0-BETA4 (which would not remove /usr/lib/libc++.so.1). But I believe you did 13.2 -> 14.0-BETA4 directly?
Comment 33 Tomoaki AOKI 2023-10-11 17:02:50 UTC
(In reply to Alan Somers from comment #27)

`make delete-old-libs` shouldn't be done until all needed non-base softwares, including ports/pkgs and possibly other "wild" ones, are rebuilt/reinstalled.
So freebsd-update shouldn't run `make delete-old-libs`, as freebsd-update cannot assure all non-base softwares are finished reinstalling for new base.
Comment 34 Dimitry Andric freebsd_committer freebsd_triage 2023-10-11 17:23:18 UTC
(In reply to Tomoaki AOKI from comment #33)
In this special case it should be no problem: the new copy libc++.so.1 strictly has _more_ functionality than the old one, and "old" applications linked against it should run without problems.

That said, for other libraries they are usually only put in OLD_LIBS when their soversion gets bumped, and indeed then you should not delete the previous library until you are sure all dependents are upgraded to the new soversion.
Comment 35 Ed Maste freebsd_committer freebsd_triage 2023-10-11 17:23:43 UTC
(In reply to Tomoaki AOKI from comment #33)
freebsd-update does not run `make delete-old-libs` but it performs the logically the same operation, on the third invocation of `freebsd-update install`.

The first invocation installs the new kernel, the second installs/updates files, and old libraries are removed by the third invocation. It informs the user that they need to rebuild/reinstall third party applications before that third invocation.
Comment 36 Joel Bodenmann freebsd_committer freebsd_triage 2023-10-11 22:16:57 UTC
(In reply to Dimitry Andric from comment #28)
In my case (the stable/13 to stable/13 upgrade) I do indeed have both present:

➜  test2 find /lib -name 'libc++.so.1'
/lib/libc++.so.1
➜  test2 find /usr/lib -name 'libc++.so.1'
/usr/lib/libc++.so.1

The minimal test case does appear (!) to link to the /lib/libc++.so.1 tho:

➜  test2 ldd test-mbr
test-mbr:
	libc++.so.1 => /lib/libc++.so.1 (0x336f31691000)
	libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x336f320fa000)
	libm.so.5 => /lib/libm.so.5 (0x336f3297a000)
	libc.so.7 => /lib/libc.so.7 (0x336f34286000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x336f33612000)
	[vdso] (0x7ffffffff650)
Comment 37 Joel Bodenmann freebsd_committer freebsd_triage 2023-10-11 22:28:52 UTC
A bit more analysis for my case based on comments #22 and #23:

# file /usr/lib/libc++.so.1     
/usr/lib/libc++.so.1: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 13.2 (1302508), stripped

# file /lib/libc++.so.1 
/lib/libc++.so.1: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 14.0 (1400057), stripped

So clearly both are present on my system too. I'm a bit confused here as I am almost entirely certain that I only ever upgraded this machine from one stable/13 commit to the next stable/13 commit.
Comment 38 Mark Millard 2023-10-11 22:31:35 UTC
(In reply to Joel Bodenmann from comment #37)

Might one of those 2 be a symbolic link to the other?

If not, are the two files any different in content?
Comment 39 Joel Bodenmann freebsd_committer freebsd_triage 2023-10-11 22:35:55 UTC
(In reply to Mark Millard from comment #38)

# ls -lhs /lib/libc++.so.1
413 -r--r--r--  1 root  wheel   823K Apr 24  2022 /lib/libc++.so.1

# ls -lhs /usr/lib/libc++.so.1 
509 -r--r--r--  1 root  wheel   1.0M Oct 10 19:22 /usr/lib/libc++.so.1

Curious about that date of the /lib version...
Comment 40 Mark Millard 2023-10-11 23:18:13 UTC
(In reply to Joel Bodenmann from comment #39)

Looking at a recent 13.2-STABLE snapshot (aarch64 for RPI) dd'd to USB3 media:

# file /mnt/lib/libc++*
/mnt/lib/libc++*: cannot open `/mnt/lib/libc++*' (No such file or directory)

NOTE: The above was also true of 13.2-RELEASE's snapshot.

# file /mnt/usr/lib/libc++*
/mnt/usr/lib/libc++.a:             current ar archive
/mnt/usr/lib/libc++.so:            ASCII text
/mnt/usr/lib/libc++.so.1:          ELF 64-bit LSB shared object, ARM aarch64, version 1 (FreeBSD), dynamically linked, for FreeBSD 13.2 (1302508), stripped
/mnt/usr/lib/libc++_p.a:           current ar archive
/mnt/usr/lib/libc++experimental.a: current ar archive

# ls -Tlod /mnt/usr/lib/libc++*
-r--r--r--  1 root wheel uarch 15281882 Oct  5 02:09:58 2023 /mnt/usr/lib/libc++.a
-r--r--r--  1 root wheel uarch       52 Oct  5 02:09:58 2023 /mnt/usr/lib/libc++.so
-r--r--r--  1 root wheel uarch  1048240 Oct  5 02:09:58 2023 /mnt/usr/lib/libc++.so.1
-r--r--r--  1 root wheel uarch 15506004 Oct  5 02:09:58 2023 /mnt/usr/lib/libc++_p.a
-r--r--r--  1 root wheel uarch   156378 Oct  5 02:09:58 2023 /mnt/usr/lib/libc++experimental.a

Looks like you might want to delete any /lib/libc++* . No clue if you have
other oddities around and so need a larger cleanup.
Comment 41 Mark Millard 2023-10-11 23:20:17 UTC
(In reply to Mark Millard from comment #40)
(In reply to Joel Bodenmann from comment #39)

# file /lib/libc++.so.1

before deletion might be interesting.
Comment 42 Daniel Ebdrup Jensen freebsd_committer freebsd_triage 2023-10-12 09:33:25 UTC
I can confirm that deleting the library works, and I'm pretty sure I know why I ran into it in the first place, as well:
I use src/tools/build/beinstall.sh by will@ as part of my upgrade routine, so I've gotten out of the habit of thinking too much about upgrades, since combining it with bectl -t means failed upgrades can be solved by simply power-cycling the machine.
This means that I completely forgot about the delete-old-libs target for make.

So since the issue has a solution, and there appears to be no actual fix needed, I'll leave this open for a bit longer, then close it as fixed if nobody has anything to add to it.

(In reply to Mark Millard from comment #41)
Well, asomers@ already ran it in comment #22, but I went ahead and did it too:

# file /usr/lib/libc++.so.1
/usr/lib/libc++.so.1: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 14.0 (1400045), stripped
# file /lib/libc++.so.1
/lib/libc++.so.1: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 14.0 (1400096), stripped
Comment 43 mmatalka 2023-10-12 11:49:08 UTC
So what is the resolution here?  I am running into this as well and I'm installing from source.  Am I missing a step in the installation process?
Comment 44 Dimitry Andric freebsd_committer freebsd_triage 2023-10-12 12:06:57 UTC
(In reply to mmatalka from comment #43)
After installworld, you are normally supposed to run:

make delete-old

which prompts you to delete old files and libraries.

Because you were just done installing the rebuilt base system, all base system binaries should only link to *new* shared libraries, so any old shared libraries can normally be cleaned up.

However, if you have ports installed, some of those ports may still require old shared libraries, so before deleting those shared libraries, you would have to make sure ports are upgraded, and/or reinstalled from a newer source.

Finally, libc++.so.1 is an exception to this later "rule", since it not only got rebuilt with new functionality, but also moved from /usr/lib to /lib.

E.g. in all cases, when you have a /lib/libc++.so.1, the old /usr/lib/libc++.so.1 should be deleted. There should be only one copy of this shared library on your system.
Comment 45 Mark Millard 2023-10-12 20:46:55 UTC
(In reply to Dimitry Andric from comment #44)

For 14.0+/15 anyway.

One of the examples in the comments is Joel Bodenmann's odd
case of also having 2022 /lib/libc++* material in a stable/13
context, predating the move from /usr/lib/libc++* . In a
13.* context, so far as I know, it is the /lib/libc++*
material that is in the wrong place and likely is of the
wrong vintage, so likely needing the delete.

How Joel B. got libc++* materials in both places may well be
completely different than the other examples. But the result
is a somewhat analogous problem.
Comment 46 Tomoaki AOKI 2023-10-12 22:16:27 UTC
(In reply to Joel Bodenmann from comment #39)

Did you manually copy /usr/lib/libc++.so.1 to /lib/libc++.so.1 for some reason?
Or any script included in what you installed did so?

Just a possibility, but something ran on very early boot stage could need it.
(For net boot case? Not sure.)

The commit Dimitry mentioned on Comment 23 has

"If desired we can stop linking devd statically after this change (to
 achive approximately no net change in required root filesystem size)."

in its commit message.

Usually, non-base software like in ports should install its rc.c scripts under /usr/loca/etc/rc.d/, but something required to run on very early stage which /usr/local/ is not assured to be mounted could irregularly install it into /etc/rc.d, not sure such softwares are in ports, though. And for such soltwares, if it requires libc++.so[.*] to run, libc++.so[.*] must be in /lib.
Comment 47 commit-hook freebsd_committer freebsd_triage 2023-10-13 19:50:34 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=922337e8d3989e4f54a0338b7fc397e3e0af7832

commit 922337e8d3989e4f54a0338b7fc397e3e0af7832
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2023-10-13 18:06:58 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2023-10-13 19:50:07 +0000

    Handle MOVED_LIBS in list-old-files

    MOVED_LIBS is used when a library moves from one directory to another,
    e.g. /usr/lib/libc++.so.1 to /lib/libc++.so.1.

    delete-old-files and delete-old-libs are two separate steps, so that
    old libraries can be retained until third party software packages are
    rebuilt or reinstalled.

    Having two copies of the same shared library with the same so version
    (as can happen when delete-old-libs hasn't been run) causes trouble.
    The PR below gives one example.

    Libraries listed in MOVED_LIBS are logically equivalent to updating a
    library without changing the so version, and should be removed as soon
    as possible.  Handle them in list-old-files and thus delete-old-files.

    Leave them also in *-old-libs for now, in case the user updates their
    tree between running delete-old-files and delete-old-libs.

    PR:             272642
    Reviewed by:    dim
    MFC after:      3 days
    Sponsored by:   The FreeBSD Foundation
    Co-authored-by: Dimitry Andric <dim@FreeBSD.org>
    Differential Revision: https://reviews.freebsd.org/D42197

 Makefile.inc1 | 1 +
 1 file changed, 1 insertion(+)
Comment 48 commit-hook freebsd_committer freebsd_triage 2023-10-16 12:30:30 UTC
A commit in branch stable/14 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=73099785902d750f96d07f2c413db062bf0e47bd

commit 73099785902d750f96d07f2c413db062bf0e47bd
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2023-10-13 18:06:58 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2023-10-16 12:29:46 +0000

    Handle MOVED_LIBS in list-old-files

    MOVED_LIBS is used when a library moves from one directory to another,
    e.g. /usr/lib/libc++.so.1 to /lib/libc++.so.1.

    delete-old-files and delete-old-libs are two separate steps, so that
    old libraries can be retained until third party software packages are
    rebuilt or reinstalled.

    Having two copies of the same shared library with the same so version
    (as can happen when delete-old-libs hasn't been run) causes trouble.
    The PR below gives one example.

    Libraries listed in MOVED_LIBS are logically equivalent to updating a
    library without changing the so version, and should be removed as soon
    as possible.  Handle them in list-old-files and thus delete-old-files.

    Leave them also in *-old-libs for now, in case the user updates their
    tree between running delete-old-files and delete-old-libs.

    PR:             272642
    Reviewed by:    dim
    Sponsored by:   The FreeBSD Foundation
    Co-authored-by: Dimitry Andric <dim@FreeBSD.org>
    Differential Revision: https://reviews.freebsd.org/D42197

    (cherry picked from commit 922337e8d3989e4f54a0338b7fc397e3e0af7832)

 Makefile.inc1 | 1 +
 1 file changed, 1 insertion(+)
Comment 49 commit-hook freebsd_committer freebsd_triage 2023-10-16 22:54:44 UTC
A commit in branch releng/14.0 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=7bc17b59f802d313b72930030e20e664a1c42ea2

commit 7bc17b59f802d313b72930030e20e664a1c42ea2
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2023-10-13 18:06:58 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2023-10-16 22:48:57 +0000

    Handle MOVED_LIBS in list-old-files

    MOVED_LIBS is used when a library moves from one directory to another,
    e.g. /usr/lib/libc++.so.1 to /lib/libc++.so.1.

    delete-old-files and delete-old-libs are two separate steps, so that
    old libraries can be retained until third party software packages are
    rebuilt or reinstalled.

    Having two copies of the same shared library with the same so version
    (as can happen when delete-old-libs hasn't been run) causes trouble.
    The PR below gives one example.

    Libraries listed in MOVED_LIBS are logically equivalent to updating a
    library without changing the so version, and should be removed as soon
    as possible.  Handle them in list-old-files and thus delete-old-files.

    Leave them also in *-old-libs for now, in case the user updates their
    tree between running delete-old-files and delete-old-libs.

    PR:             272642
    Reviewed by:    dim
    Sponsored by:   The FreeBSD Foundation
    Co-authored-by: Dimitry Andric <dim@FreeBSD.org>
    Differential Revision: https://reviews.freebsd.org/D42197

    (cherry picked from commit 922337e8d3989e4f54a0338b7fc397e3e0af7832)
    (cherry picked from commit 73099785902d750f96d07f2c413db062bf0e47bd)

    Approved by:    re (karels)

 Makefile.inc1 | 1 +
 1 file changed, 1 insertion(+)
Comment 50 Dimitry Andric freebsd_committer freebsd_triage 2023-10-18 21:38:53 UTC
Is there any more to be done on this issue now? I think we can close it?
Comment 51 Alan Somers freebsd_committer freebsd_triage 2023-10-18 21:45:28 UTC
(In reply to Dimitry Andric from comment #50)
As far as I'm concerned, yes it's fixed.
Comment 52 commit-hook freebsd_committer freebsd_triage 2023-11-01 14:32:49 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=f38bad0ab0fca9b1f665b2ba79098edf993c0854

commit f38bad0ab0fca9b1f665b2ba79098edf993c0854
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2023-10-16 12:46:31 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2023-11-01 14:32:31 +0000

    Remove MOVED_LIBS handling from list-old-libs

    In 922337e8d398 I added MOVED_LIBS into list-old-files, so that
    delete-old-files would remove the old /usr/lib/libc++.so.1 as soon as
    possible (after the library moved to /lib).

    I left it in list-old-libs in case a user updated their src tree between
    delete-old-files and delete-old-libs.  Now that some time has passed,
    tremove the redundant MOVED_LIBS entry.

    PR:             272642
    Sponsored by:   The FreeBSD Foundation

 Makefile.inc1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Comment 53 commit-hook freebsd_committer freebsd_triage 2024-02-26 23:18:44 UTC
A commit in branch stable/14 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=26db5b3e638ee09a21b6554003a2257fd6e285a4

commit 26db5b3e638ee09a21b6554003a2257fd6e285a4
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2023-10-16 12:46:31 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2024-02-26 23:18:08 +0000

    Remove MOVED_LIBS handling from list-old-libs

    In 922337e8d398 I added MOVED_LIBS into list-old-files, so that
    delete-old-files would remove the old /usr/lib/libc++.so.1 as soon as
    possible (after the library moved to /lib).

    I left it in list-old-libs in case a user updated their src tree between
    delete-old-files and delete-old-libs.  Now that some time has passed,
    tremove the redundant MOVED_LIBS entry.

    PR:             272642
    Sponsored by:   The FreeBSD Foundation

    (cherry picked from commit f38bad0ab0fca9b1f665b2ba79098edf993c0854)

 Makefile.inc1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)