[libunwind] relation between llvm libunwind and nongnu libunwind


I'm currently maintaining the llvm-libunwind package in Gentoo Linux.
I noticed there're two libunwind's out there, one from llvm and the
other from nongnu.

I couldn't find much documentation on this topic. At a glimpse, these
two libs seem very similar yet not 100% same. Is llvm's libunwind
intended to be ABI compatible with nongnu's? or just to be
functionally equivalent to it?

To add to my confusion, I found libunwind's header unwind.h is also
internally defined by gcc/clang. I did some testing; it seems
gcc/clang's internal unwind.h just work with libunwind's library. So
what's the relation among those variants of unwind.h? Is it a good
idea to mix-use them?



The ‘nongnu’ libunwind is a continuation of HP’s libunwind. This was created as a complete unwinder library, with support for unwinding the current thread, another thread in the same process, and even another thread in a different process using the DWARF unwind metadata.

This libunwind was created for Itanium, where it was effectively impossible to implement setjmp / longjmp in the conventional way and so some other mechanism was required to unwind the stack. As well as the remote unwinding APIs, it implemented the bottom part of the Itanium System V exception ABI spec, which is now used by pretty much all *NIX variants architectures on all architectures except AArch32 (except NetBSD).

Most of the other uses (remote unwinding and so on) for HP's libunwind didn’t materialise (or, if they did, were very rare) and so it ended up being a very complicated implementation of a fairly simple set of interfaces[1].

The libUnwind in the LLVM repository was originally created by Apple and is much simpler. It is intended to be a small and fast implementation of the base ABI, and nothing more.

For 99% of cases (throwing exceptions, force unwinding the stack, walking the stack to generate a stack trace), either can be used interchangeably (slightly less true on ARM, I believe, but probably there also). The interfaces defined in unwind.h are, for the most part, standard APIs and are implemented in compatible ways by either.

There are a few things for which only a derivative of the HP libunwind (I know of three active forks, though the nongnu one is most visible) will do.


[1] https://mentorembedded.github.io/cxx-abi/abi-eh.html#base-abi

The classic setjmp/longjmp would be used on Itanium just as well. It was
expensive due to the huge register set, but that's the only problem it
ever had. Even that is more a question of how many registers actually
have to be preserved...


I did notice that LLVM's libunwind has a few symbols that are
unavailable in the nongnu one, including __register_frame and
__deregister_frame. I once tried building llvm itself against the
nongnu libunwind, and failed due to missing those symbols. I don't
know if they are also part of the unwinding ABI.