Page MenuHomeFreeBSD

Add libunwind.so.1 from llvm-project
Needs ReviewPublic

Authored by dim on Jun 21 2025, 12:13 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Oct 14, 4:45 PM
Unknown Object (File)
Sep 13 2025, 8:18 PM
Unknown Object (File)
Sep 13 2025, 3:42 PM
Unknown Object (File)
Sep 12 2025, 6:07 AM
Unknown Object (File)
Sep 11 2025, 7:26 PM
Unknown Object (File)
Sep 10 2025, 6:47 AM
Unknown Object (File)
Sep 7 2025, 3:38 PM
Unknown Object (File)
Sep 3 2025, 11:41 PM
Subscribers

Details

Summary

This adds libunwind.so.1, built from the same sources as libgcc_eh.a
currently is, but with -fPIC.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 65008
Build 61891: arc lint + arc unit

Event Timeline

dim requested review of this revision.Jun 21 2025, 12:13 PM
dim created this revision.

Note that this may require a ports exp-run? I'd expect some stuff to fall over.

What is the motivation? Is the intention for ports to start using this instead of, say, devel/libunwind?

Gleb started a discussion here: https://lists.freebsd.org/archives/freebsd-toolchain/2025-June/002326.html

I noticed that we install the /usr/include/libunwind.h file, which can be picked by ports, but symbols from this header are defined in the /usr/lib/libgcc_eh.a static library. I find this a bit surprising.

If this header is intended to be public, then we should have libunwind.so in base, so that programs can link to it. Otherwise, we should hide the header and make ports use devel/libunwind or devel/llvmXY instead.

In D50964#1163718, @jhb wrote:

What is the motivation? Is the intention for ports to start using this instead of, say, devel/libunwind?

Exactly. Right now lang/dotnet uses devel/libunwind and it has a heisenbug that sometimes causes build to crash. I was hoping that using LLVM libunwind would fix the issue.

Ah, hmm. The intention of the commit in 2022 was really about unifying unwind.h. I think I hadn't realized the libunwind.h implied something else. Do we think that the base system libunwind is as feature complete as devel/libunwind? If so, I'm happy to move forward with this change. Alternatively, we could stop installing libunwind.h? @jrtc27 might have an opinion as well?

Do we think that the base system libunwind is as feature complete as devel/libunwind?

FWIW, I managed to compile lang/dotnet against base libunwind.h and libgcc_eh.a just fine.

If needed I can run a mini exp-run on ports with this change applied and devel/libunwind disabled akin to https://reviews.freebsd.org/D50736

I stumbled upon this code block, which confuses me: https://github.com/llvm/llvm-project/blob/84c849e85b0f8ab2d8bbeb2d9c46349f019f4e8e/clang/lib/Driver/ToolChains/FreeBSD.cpp#L329-L337

It seems that it is libgcc_s.so is used as a dynamic version of libgcc_eh.a?

Yes, clang/gcc already use libgcc_s to provide support routines needed for C++ exceptions, so this is already linked into C++ binaries today. It may be that we only want to symlink libunwind.so to libgcc_s.so rather than building a separate library? This would let -lunwind work while avoiding duplicate symbols, etc.

The following program

#include <libunwind.h>

int main(int argc, char* argv[])
{
        unw_context_t ctx;
        return unw_getcontext(&ctx);
}

fails to link with cc unw.c -lgcc_s, but works with cc unw.c -lgcc_eh. So these two libraries aren't really counterparts.

The following program

#include <libunwind.h>

int main(int argc, char* argv[])
{
        unw_context_t ctx;
        return unw_getcontext(&ctx);
}

fails to link with cc unw.c -lgcc_s, but works with cc unw.c -lgcc_eh. So these two libraries aren't really counterparts.

Yeah, that is correct. Historically libgcc_s didn't contain the unw_xxx functions, but mostly gcc's compiler support routines. For llvm-project this role is taken by compiler-rt, which we have installed as libgcc_s.so, so as to not have to recompile all clients.

So, like I said, I can perform a Ports exp-run with devel/libunwind replaced with the base library from this change. Would this help move this forward?

How do we move this forward? It feels to me that the main problem is that nobody is certain what are the consequences of making this library public?

I think an exp-run is probably the next step.

I still don't understand how libgcc_s is failing to link. libgcc_s already includes libgcc_eh/Makefile.inc so should include all those symbols. Ah, it has a symbol map, so does not export all of the symbols.

I wonder if we want to ensure that libunwind doesn't duplicate symbols from libgcc_s? (Do we care?) If we do care, the fix for that might be to use a Symbol.map to restrict which symbols are exported by the native libunwind so it doesn't conflict with libgcc_s.so?

Here are results after my exp-run:

  1. We need to install /usr/libdata/pkgconfig/libunwind.pc with something like
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: libunwind
Description: libunwind base library
Version: ???
Libs: -L${libdir} -lunwind
Cflags: -I${includedir}
  1. Our libunwind is missing following stuff that is being used by ports:
  • Functions unw_strerror, unw_init_remote, unw_create_addr_space, unw_backtrace, unw_backtrace_skip, unw_set_cache_size, unw_set_caching_policy
  • Defines UNW_VERSION_MAJOR, UNW_VERSION_MINOR
  • Header libunwind-ptrace.h with extern unw_accessors_t _UPT_accessors

Which brings us to question if LLVM libunwind is really intended to be used instead of the nongnu one. If it isn't then the whole idea of exposing this library from base might be wrong. Otherwise, maybe we should ask LLVM upstream to add the missing bits.