mirror of
https://github.com/OPM/ResInsight.git
synced 2026-11-02 20:30:46 -06:00
#14720 Probe std::stacktrace by linking instead of trusting the feature macro
libstdc++ defines __cpp_lib_stacktrace from GCC 13 on, but the implementation lives in libstdc++exp, which some distributions do not ship (Red Hat's gcc-toolset among them). The header-only feature test then reports the feature as present and the link fails with undefined references to std::__stacktrace_impl::_S_current. Add cmake/StdStacktrace.cmake, which probes the feature by actually linking: first with no extra library, then with stdc++exp. The result selects the link library through RESINSIGHT_STACKTRACE_LIBRARIES, or defines RIA_HAS_STD_STACKTRACE=0 project-wide when neither links, so the crash handler compiles out its stack-trace capture and logs the signal only. RiaMainTools.cpp and RiaOpenTelemetryManager.h now honour a RIA_HAS_STD_STACKTRACE definition from the build system and only include <stacktrace> when the feature is enabled. Follow-up to #14045.
This commit is contained in:
1 parent
aa3ec82e1c
commit
3f7aee5972
5 files changed
+105
-38
No files matched your search
@@ -40,17 +40,20 @@
|
|||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <version>
|
#include <version>
|
||||||
|
|
||||||
// std::stacktrace is C++23; libc++ in Homebrew llvm@19 (and older) does not
|
// std::stacktrace is C++23 and not usable on all toolchains. The build system
|
||||||
// ship it. Without it we skip stack-trace capture in the crash path but
|
// probes it by linking and may force it off via RIA_HAS_STD_STACKTRACE=0, see
|
||||||
// still log the signal. Use the feature-test macro from <version> rather
|
// cmake/StdStacktrace.cmake and #14045.
|
||||||
// than __has_include, since the header may be present without a usable
|
#ifndef RIA_HAS_STD_STACKTRACE
|
||||||
// implementation. See #14045.
|
|
||||||
#if defined( __cpp_lib_stacktrace ) && __cpp_lib_stacktrace >= 202011L
|
#if defined( __cpp_lib_stacktrace ) && __cpp_lib_stacktrace >= 202011L
|
||||||
#include <stacktrace>
|
|
||||||
#define RIA_HAS_STD_STACKTRACE 1
|
#define RIA_HAS_STD_STACKTRACE 1
|
||||||
#else
|
#else
|
||||||
#define RIA_HAS_STD_STACKTRACE 0
|
#define RIA_HAS_STD_STACKTRACE 0
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if RIA_HAS_STD_STACKTRACE
|
||||||
|
#include <stacktrace>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|||||||
@@ -31,17 +31,20 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <version>
|
#include <version>
|
||||||
|
|
||||||
// std::stacktrace is C++23. libc++ shipped with Homebrew llvm@19 (and
|
// std::stacktrace is C++23 and not usable on all toolchains. The build system
|
||||||
// older toolchains) does not provide it yet, so guard the include + the
|
// probes it by linking and may force it off via RIA_HAS_STD_STACKTRACE=0, see
|
||||||
// reportCrash overload that uses it. Use the feature-test macro from
|
// cmake/StdStacktrace.cmake and #14045.
|
||||||
// <version> rather than __has_include, since the header may be present
|
#ifndef RIA_HAS_STD_STACKTRACE
|
||||||
// without a usable implementation. See #14045.
|
|
||||||
#if defined( __cpp_lib_stacktrace ) && __cpp_lib_stacktrace >= 202011L
|
#if defined( __cpp_lib_stacktrace ) && __cpp_lib_stacktrace >= 202011L
|
||||||
#include <stacktrace>
|
|
||||||
#define RIA_HAS_STD_STACKTRACE 1
|
#define RIA_HAS_STD_STACKTRACE 1
|
||||||
#else
|
#else
|
||||||
#define RIA_HAS_STD_STACKTRACE 0
|
#define RIA_HAS_STD_STACKTRACE 0
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if RIA_HAS_STD_STACKTRACE
|
||||||
|
#include <stacktrace>
|
||||||
|
#endif
|
||||||
|
|
||||||
class QString;
|
class QString;
|
||||||
class QNetworkAccessManager;
|
class QNetworkAccessManager;
|
||||||
|
|||||||
@@ -321,34 +321,12 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||||||
# According to ivarun rt is needed on OpenSuse, and Fedora. See:
|
# According to ivarun rt is needed on OpenSuse, and Fedora. See:
|
||||||
# https://github.com/OPM/ResInsight/pull/7
|
# https://github.com/OPM/ResInsight/pull/7
|
||||||
list(APPEND EXTERNAL_LINK_LIBRARIES rt)
|
list(APPEND EXTERNAL_LINK_LIBRARIES rt)
|
||||||
|
|
||||||
# std::stacktrace requires stdc++exp. If a custom build of GCC stdc++exp is
|
|
||||||
# required, define the search path here.
|
|
||||||
set(RESINSIGHT_GCC_STDCPP_EXP_PATH
|
|
||||||
""
|
|
||||||
CACHE PATH "Path to search for stdc++exp"
|
|
||||||
)
|
|
||||||
|
|
||||||
if(RESINSIGHT_GCC_STDCPP_EXP_PATH)
|
|
||||||
find_library(
|
|
||||||
STDCPP_EXP_LIBRARY
|
|
||||||
NAMES stdc++exp
|
|
||||||
HINTS ${RESINSIGHT_GCC_STDCPP_EXP_PATH}
|
|
||||||
)
|
|
||||||
if(STDCPP_EXP_LIBRARY)
|
|
||||||
message(
|
|
||||||
STATUS
|
|
||||||
"stdc++exp library found at custom location: ${STDCPP_EXP_LIBRARY}"
|
|
||||||
)
|
|
||||||
list(APPEND EXTERNAL_LINK_LIBRARIES ${STDCPP_EXP_LIBRARY})
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
# stdc++exp is required for std::stacktrace
|
|
||||||
message(STATUS "stdc++exp library found at default location")
|
|
||||||
list(APPEND EXTERNAL_LINK_LIBRARIES stdc++exp)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# std::stacktrace needs stdc++exp on most libstdc++ toolchains. Which library,
|
||||||
|
# if any, is probed in cmake/StdStacktrace.cmake.
|
||||||
|
list(APPEND EXTERNAL_LINK_LIBRARIES ${RESINSIGHT_STACKTRACE_LIBRARIES})
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
ApplicationLibCode PUBLIC ${LINK_LIBRARIES} ${EXTERNAL_LINK_LIBRARIES}
|
ApplicationLibCode PUBLIC ${LINK_LIBRARIES} ${EXTERNAL_LINK_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -140,6 +140,8 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNO_DEBUG")
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNO_DEBUG")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(cmake/StdStacktrace.cmake)
|
||||||
|
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
# Asserts
|
# Asserts
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
# ##############################################################################
|
||||||
|
# std::stacktrace availability
|
||||||
|
#
|
||||||
|
# libstdc++ has shipped <stacktrace> and defined __cpp_lib_stacktrace since GCC
|
||||||
|
# 13, but the implementation lives in a separate library (libstdc++exp). Some
|
||||||
|
# distributions ship the headers without that library -- Red Hat's gcc-toolset
|
||||||
|
# is one -- so the header-only feature test in RiaMainTools.cpp and
|
||||||
|
# RiaOpenTelemetryManager.h reports the feature as present and the link then
|
||||||
|
# fails with undefined references to std::__stacktrace_impl::_S_current.
|
||||||
|
#
|
||||||
|
# Probe by actually linking: first with no extra library (libc++, and any
|
||||||
|
# libstdc++ that folds the implementation in), then with stdc++exp, from
|
||||||
|
# RESINSIGHT_GCC_STDCPP_EXP_PATH when a custom GCC build is used. If neither
|
||||||
|
# links, define RIA_HAS_STD_STACKTRACE=0 for the whole project so the crash
|
||||||
|
# handler compiles out its stack-trace capture and logs the signal only.
|
||||||
|
#
|
||||||
|
# Sets RESINSIGHT_STACKTRACE_LIBRARIES for the link line (empty when the
|
||||||
|
# feature needs no extra library, or is unavailable).
|
||||||
|
# ##############################################################################
|
||||||
|
|
||||||
|
include(CheckCXXSourceCompiles)
|
||||||
|
include(CMakePushCheckState)
|
||||||
|
|
||||||
|
set(RESINSIGHT_GCC_STDCPP_EXP_PATH
|
||||||
|
""
|
||||||
|
CACHE PATH "Path to search for stdc++exp"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(RESINSIGHT_STACKTRACE_LIBRARIES "")
|
||||||
|
|
||||||
|
set(_ri_stacktrace_source
|
||||||
|
"#include <stacktrace>
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return static_cast<int>( std::stacktrace::current().size() );
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
|
||||||
|
cmake_push_check_state(RESET)
|
||||||
|
check_cxx_source_compiles(
|
||||||
|
"${_ri_stacktrace_source}" RESINSIGHT_STACKTRACE_NO_EXTRA_LIBRARY
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT RESINSIGHT_STACKTRACE_NO_EXTRA_LIBRARY)
|
||||||
|
# Default to the plain library name and let the compiler driver resolve it
|
||||||
|
# from its own library directories, which find_library() does not search.
|
||||||
|
set(_ri_stdcpp_exp stdc++exp)
|
||||||
|
if(RESINSIGHT_GCC_STDCPP_EXP_PATH)
|
||||||
|
find_library(
|
||||||
|
STDCPP_EXP_LIBRARY
|
||||||
|
NAMES stdc++exp
|
||||||
|
HINTS ${RESINSIGHT_GCC_STDCPP_EXP_PATH}
|
||||||
|
)
|
||||||
|
if(STDCPP_EXP_LIBRARY)
|
||||||
|
set(_ri_stdcpp_exp ${STDCPP_EXP_LIBRARY})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${_ri_stdcpp_exp})
|
||||||
|
check_cxx_source_compiles(
|
||||||
|
"${_ri_stacktrace_source}" RESINSIGHT_STACKTRACE_NEEDS_STDCPP_EXP
|
||||||
|
)
|
||||||
|
if(RESINSIGHT_STACKTRACE_NEEDS_STDCPP_EXP)
|
||||||
|
set(RESINSIGHT_STACKTRACE_LIBRARIES ${_ri_stdcpp_exp})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
cmake_pop_check_state()
|
||||||
|
|
||||||
|
if(RESINSIGHT_STACKTRACE_NO_EXTRA_LIBRARY)
|
||||||
|
message(STATUS "std::stacktrace: available, no extra library required")
|
||||||
|
elseif(RESINSIGHT_STACKTRACE_NEEDS_STDCPP_EXP)
|
||||||
|
message(
|
||||||
|
STATUS "std::stacktrace: available, linking ${RESINSIGHT_STACKTRACE_LIBRARIES}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(
|
||||||
|
STATUS
|
||||||
|
"std::stacktrace: not usable with this toolchain (no stdc++exp), crash handler will log signals without stack traces"
|
||||||
|
)
|
||||||
|
add_compile_definitions(RIA_HAS_STD_STACKTRACE=0)
|
||||||
|
endif()
|
||||||
Reference in new issue
Block a user