boostorg / stacktrace

C++ library for storing and printing backtraces.
https://boost.org/libs/stacktrace
422 stars 69 forks source link

stacktrace_from_exception on non-x86 #163

Open hainest opened 4 months ago

hainest commented 4 months ago

I submitted the below to the mailing list, but I wanted to re-iterate it here for more eyes. https://lists.boost.org/Archives/boost/2024/04/256604.php

This feature is guarded by BOOST_STACKTRACE_ALWAYS_STORE_IN_PADDING, but that is only enabled on x86. This means that

./bootstrap.sh --with-toolset=gcc --with-libraries=stacktrace
./b2 install threading=multi toolset=gcc

always fails to build on non-x86 platforms. There are three current workarounds:

  1. set boost.stacktrace.from_exception=off
  2. set BOOST_STACKTRACE_LIBCXX_RUNTIME_MAY_CAUSE_MEMORY_LEAK
  3. build with threading=single

(1) prevents me from using this feature. (2) shouldn't be needed on it's face because I'm using gcc/libstdc++. (3) affects more than stacktrace.

Is this an incidental error, or is there a reason I wasn't able to deduce as to why this feature can't be used on non-x86+libstdc++?

It seems like the check for libc++ on non-x86 can't be entirely done at compile time. I definitely understand wanting to alert users to the dangers of using this feature, but there also doesn't seem to be a good way of detecting the presence of libc++ at compile time (hence the need for is_libcpp_runtime).

apolukhin commented 3 months ago

(2) shouldn't be needed on it's face because I'm using gcc/libstdc++

There are many people who use other runtimes and there's no known to me way to detect that. How should I warn them to avoid some runtimes or to be ready for leaks?

hainest commented 3 months ago

@apolukhin I did some exploring on this some time ago for detecting minimum versions of lib{std}c++ using _LIBCPP_GLIBC_PREREQ to detect libc++.

#include <features.h>

int main() {

// Starting with libc++-6, the glibc macro is in the libcpp namespace
#if defined _LIBCPP_GLIBC_PREREQ
# if _LIBCPP_GLIBC_PREREQ(LIBC_MAJOR, LIBC_MINOR)
    return 1;
# endif
#endif

}

It was succesful for gc/clang on Ubuntu, but I didn't ever get around to doing a more thorough anaysis. The comment on namespacing referes to https://reviews.llvm.org/D41892, so this method is not 100% accurate.

It looks like FreeBSD has been using libc++ since version 10 (https://wiki.freebsd.org/NewC%2B%2BStack) and OpenBSD appears to support both via clang (https://man.openbsd.org/intro.3). I'm assuming Mac uses libc++, as well. I know nothing about other platforms.