From b21de511c334e8a68d16db31da433a67eda3eda9 Mon Sep 17 00:00:00 2001 From: Fedor Osetrov Date: Wed, 25 Mar 2026 18:30:38 +0000 Subject: [PATCH 1/9] support import std --- CMakeLists.txt | 45 +++++++++++++------ include/boost/stacktrace/detail/addr_base.hpp | 2 + .../boost/stacktrace/detail/frame_decl.hpp | 2 + .../boost/stacktrace/detail/frame_unwind.ipp | 2 + .../boost/stacktrace/detail/to_dec_array.hpp | 2 + .../boost/stacktrace/detail/to_hex_array.hpp | 2 + .../boost/stacktrace/detail/void_ptr_cast.hpp | 2 + include/boost/stacktrace/frame.hpp | 2 + include/boost/stacktrace/safe_dump_to.hpp | 2 + include/boost/stacktrace/stacktrace.hpp | 2 + include/boost/stacktrace/stacktrace_fwd.hpp | 2 + modules/boost_stacktrace_addr2line.cppm | 6 +++ modules/boost_stacktrace_backtrace.cppm | 6 +++ modules/boost_stacktrace_basic.cppm | 6 +++ modules/boost_stacktrace_dump.cppm | 9 +++- modules/boost_stacktrace_noop.cppm | 6 +++ .../samples/usage_sample_from_exception.cpp | 5 ++- 17 files changed, 86 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 909a353e..625f2af6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,18 +7,24 @@ cmake_minimum_required(VERSION 3.8...4.20) project(boost_stacktrace VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) -function(stacktrace_add_module name) +function(stacktrace_add_module name import_std) target_sources(${name} PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${CMAKE_CURRENT_LIST_DIR}/modules FILES ${CMAKE_CURRENT_LIST_DIR}/modules/${name}.cppm ) - target_compile_features(${name} PUBLIC cxx_std_23) target_compile_definitions(${name} PUBLIC BOOST_USE_MODULES) + + if(${import_std}) + target_compile_features(${name} PUBLIC cxx_std_23) + target_compile_definitions(${name} PRIVATE BOOST_STACKTRACE_USE_STD_MODULE) + else() + target_compile_features(${name} PUBLIC cxx_std_20) + endif() endfunction() -function(stacktrace_add_library suffix opt public_libs libs defs add_module) +function(stacktrace_add_library suffix opt public_libs libs defs add_module import_std) if(NOT opt) return() @@ -50,7 +56,7 @@ function(stacktrace_add_library suffix opt public_libs libs defs add_module) ) if (add_module) - stacktrace_add_module(boost_stacktrace_${suffix}) + stacktrace_add_module(boost_stacktrace_${suffix} ${import_std}) else() target_sources(boost_stacktrace_${suffix} PRIVATE @@ -129,23 +135,33 @@ else() set(_enable_non_noop_backend FALSE) endif() -if(NOT BOOST_USE_MODULES) +if(BOOST_USE_MODULES) + if (CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD AND CMAKE_CXX_MODULE_STD) + message(STATUS "Using `import std;`") + set(__import_std ON) + else() + message(STATUS "`import std;` is not available") + set(__import_std OFF) + endif() + unset(__standard) +else() set(BOOST_USE_MODULES OFF) + set(__import_std OFF) endif() -stacktrace_add_library(dump ${_enable_non_noop_backend} "" "" "" ${BOOST_USE_MODULES}) -stacktrace_add_library(noop ${BOOST_STACKTRACE_ENABLE_NOOP} "" "" "" ${BOOST_USE_MODULES}) -stacktrace_add_library(backtrace ${BOOST_STACKTRACE_ENABLE_BACKTRACE} Boost::stacktrace_dump "backtrace;${CMAKE_DL_LIBS}" "" ${BOOST_USE_MODULES}) -stacktrace_add_library(addr2line ${BOOST_STACKTRACE_ENABLE_ADDR2LINE} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "" ${BOOST_USE_MODULES}) -stacktrace_add_library(basic ${BOOST_STACKTRACE_ENABLE_BASIC} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "" ${BOOST_USE_MODULES}) -stacktrace_add_library(windbg ${BOOST_STACKTRACE_ENABLE_WINDBG} Boost::stacktrace_dump "dbgeng;ole32" "_GNU_SOURCE=1" ${BOOST_USE_MODULES}) -stacktrace_add_library(windbg_cached ${BOOST_STACKTRACE_ENABLE_WINDBG_CACHED} Boost::stacktrace_dump "dbgeng;ole32" "_GNU_SOURCE=1" ${BOOST_USE_MODULES}) +stacktrace_add_library(dump ${_enable_non_noop_backend} "" "" "" ${BOOST_USE_MODULES} ${__import_std}) +stacktrace_add_library(noop ${BOOST_STACKTRACE_ENABLE_NOOP} "" "" "" ${BOOST_USE_MODULES} ${__import_std}) +stacktrace_add_library(backtrace ${BOOST_STACKTRACE_ENABLE_BACKTRACE} Boost::stacktrace_dump "backtrace;${CMAKE_DL_LIBS}" "" ${BOOST_USE_MODULES} ${__import_std}) +stacktrace_add_library(addr2line ${BOOST_STACKTRACE_ENABLE_ADDR2LINE} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "" ${BOOST_USE_MODULES} ${__import_std}) +stacktrace_add_library(basic ${BOOST_STACKTRACE_ENABLE_BASIC} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "" ${BOOST_USE_MODULES} ${__import_std}) +stacktrace_add_library(windbg ${BOOST_STACKTRACE_ENABLE_WINDBG} Boost::stacktrace_dump "dbgeng;ole32" "_GNU_SOURCE=1" ${BOOST_USE_MODULES} ${__import_std}) +stacktrace_add_library(windbg_cached ${BOOST_STACKTRACE_ENABLE_WINDBG_CACHED} Boost::stacktrace_dump "dbgeng;ole32" "_GNU_SOURCE=1" ${BOOST_USE_MODULES} ${__import_std}) # boost_stacktrace, default library if(BOOST_USE_MODULES) add_library(boost_stacktrace) - stacktrace_add_module(boost_stacktrace boost_stacktrace) + stacktrace_add_module(boost_stacktrace ${__import_std}) set(__scope PUBLIC) foreach(backend noop backtrace addr2line basic windbg windbg_cached) @@ -157,6 +173,7 @@ else() add_library(boost_stacktrace INTERFACE) set(__scope INTERFACE) endif() +unset(__import_std) target_include_directories(boost_stacktrace ${__scope} "${CMAKE_CURRENT_LIST_DIR}/include") add_library(Boost::stacktrace ALIAS boost_stacktrace) @@ -182,7 +199,7 @@ target_link_libraries(boost_stacktrace ${__scope} Boost::stacktrace_${__default_ # Boost::stacktrace_from_exception is never the default if(_enable_non_noop_backend) - stacktrace_add_library(from_exception ${BOOST_STACKTRACE_ENABLE_FROM_EXCEPTION} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "" FALSE) + stacktrace_add_library(from_exception ${BOOST_STACKTRACE_ENABLE_FROM_EXCEPTION} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "" FALSE FALSE) unset(_enable_non_noop_backend) endif() diff --git a/include/boost/stacktrace/detail/addr_base.hpp b/include/boost/stacktrace/detail/addr_base.hpp index b16ac2ba..736cc6fa 100644 --- a/include/boost/stacktrace/detail/addr_base.hpp +++ b/include/boost/stacktrace/detail/addr_base.hpp @@ -12,10 +12,12 @@ # pragma once #endif +#ifndef BOOST_STACKTRACE_USE_STD_MODULE #include #include #include #include +#endif namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/frame_decl.hpp b/include/boost/stacktrace/detail/frame_decl.hpp index 28ce5645..9a506fd0 100644 --- a/include/boost/stacktrace/detail/frame_decl.hpp +++ b/include/boost/stacktrace/detail/frame_decl.hpp @@ -15,7 +15,9 @@ # pragma once #endif +#ifndef BOOST_STACKTRACE_USE_STD_MODULE #include +#endif #if !defined(BOOST_USE_MODULES) #include diff --git a/include/boost/stacktrace/detail/frame_unwind.ipp b/include/boost/stacktrace/detail/frame_unwind.ipp index 5a7cbea1..5401b5fb 100644 --- a/include/boost/stacktrace/detail/frame_unwind.ipp +++ b/include/boost/stacktrace/detail/frame_unwind.ipp @@ -20,7 +20,9 @@ #include #include +#ifndef BOOST_STACKTRACE_USE_STD_MODULE #include +#endif #ifdef BOOST_STACKTRACE_USE_BACKTRACE # include diff --git a/include/boost/stacktrace/detail/to_dec_array.hpp b/include/boost/stacktrace/detail/to_dec_array.hpp index dc5372e3..9db5a979 100644 --- a/include/boost/stacktrace/detail/to_dec_array.hpp +++ b/include/boost/stacktrace/detail/to_dec_array.hpp @@ -12,8 +12,10 @@ # pragma once #endif +#ifndef BOOST_STACKTRACE_USE_STD_MODULE #include #include // std::size_t +#endif namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/to_hex_array.hpp b/include/boost/stacktrace/detail/to_hex_array.hpp index ee9a6b15..957d389f 100644 --- a/include/boost/stacktrace/detail/to_hex_array.hpp +++ b/include/boost/stacktrace/detail/to_hex_array.hpp @@ -12,8 +12,10 @@ # pragma once #endif +#ifndef BOOST_STACKTRACE_USE_STD_MODULE #include #include +#endif namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/void_ptr_cast.hpp b/include/boost/stacktrace/detail/void_ptr_cast.hpp index f275ecfb..ebbfe1e2 100644 --- a/include/boost/stacktrace/detail/void_ptr_cast.hpp +++ b/include/boost/stacktrace/detail/void_ptr_cast.hpp @@ -13,7 +13,9 @@ # pragma once #endif +#ifndef BOOST_STACKTRACE_USE_STD_MODULE #include +#endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 301) # pragma GCC system_header diff --git a/include/boost/stacktrace/frame.hpp b/include/boost/stacktrace/frame.hpp index 5402e949..0266f81a 100644 --- a/include/boost/stacktrace/frame.hpp +++ b/include/boost/stacktrace/frame.hpp @@ -15,8 +15,10 @@ # pragma once #endif +#ifndef BOOST_STACKTRACE_USE_STD_MODULE #include #include +#endif #include #include diff --git a/include/boost/stacktrace/safe_dump_to.hpp b/include/boost/stacktrace/safe_dump_to.hpp index bd47710a..1e8726d5 100644 --- a/include/boost/stacktrace/safe_dump_to.hpp +++ b/include/boost/stacktrace/safe_dump_to.hpp @@ -19,7 +19,9 @@ # pragma once #endif +#ifndef BOOST_STACKTRACE_USE_STD_MODULE #include +#endif #if defined(BOOST_WINDOWS) #include diff --git a/include/boost/stacktrace/stacktrace.hpp b/include/boost/stacktrace/stacktrace.hpp index 5be946f5..767d63d8 100644 --- a/include/boost/stacktrace/stacktrace.hpp +++ b/include/boost/stacktrace/stacktrace.hpp @@ -18,6 +18,7 @@ #include #include +#ifndef BOOST_STACKTRACE_USE_STD_MODULE #include #include #include @@ -25,6 +26,7 @@ #ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS # include #endif +#endif #include #include diff --git a/include/boost/stacktrace/stacktrace_fwd.hpp b/include/boost/stacktrace/stacktrace_fwd.hpp index 00735c23..035ea338 100644 --- a/include/boost/stacktrace/stacktrace_fwd.hpp +++ b/include/boost/stacktrace/stacktrace_fwd.hpp @@ -11,8 +11,10 @@ #if !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) +#ifndef BOOST_STACKTRACE_USE_STD_MODULE #include #include +#endif /// @file stacktrace_fwd.hpp This header contains only forward declarations of /// boost::stacktrace::frame, boost::stacktrace::basic_stacktrace, boost::stacktrace::stacktrace diff --git a/modules/boost_stacktrace_addr2line.cppm b/modules/boost_stacktrace_addr2line.cppm index a521b4ee..4e2f8630 100644 --- a/modules/boost_stacktrace_addr2line.cppm +++ b/modules/boost_stacktrace_addr2line.cppm @@ -14,6 +14,7 @@ module; #include #include +#if !defined(BOOST_STACKTRACE_USE_STD_MODULE) #include #include #include @@ -25,12 +26,17 @@ module; #include #include #include +#endif #define BOOST_STACKTRACE_INTERFACE_UNIT #define BOOST_STACKTRACE_LINK export module boost.stacktrace.addr2line; +#if defined(BOOST_STACKTRACE_USE_STD_MODULE) +import std; +#endif + import boost.stacktrace.dump; #ifdef __clang__ diff --git a/modules/boost_stacktrace_backtrace.cppm b/modules/boost_stacktrace_backtrace.cppm index 459bfd2c..0c96a5a7 100644 --- a/modules/boost_stacktrace_backtrace.cppm +++ b/modules/boost_stacktrace_backtrace.cppm @@ -16,6 +16,7 @@ module; #include +#if !defined(BOOST_STACKTRACE_USE_STD_MODULE) #include #include #include @@ -27,6 +28,7 @@ module; #include #include #include +#endif #define BOOST_STACKTRACE_INTERFACE_UNIT #define BOOST_STACKTRACE_LINK @@ -37,6 +39,10 @@ module; export module boost.stacktrace.backtrace; +#if defined(BOOST_STACKTRACE_USE_STD_MODULE) +import std; +#endif + import boost.stacktrace.dump; #ifdef __clang__ diff --git a/modules/boost_stacktrace_basic.cppm b/modules/boost_stacktrace_basic.cppm index 5eaaaf7a..460ff34e 100644 --- a/modules/boost_stacktrace_basic.cppm +++ b/modules/boost_stacktrace_basic.cppm @@ -14,6 +14,7 @@ module; #include #include +#if !defined(BOOST_STACKTRACE_USE_STD_MODULE) #include #include #include @@ -25,12 +26,17 @@ module; #include #include #include +#endif #define BOOST_STACKTRACE_INTERFACE_UNIT #define BOOST_STACKTRACE_LINK export module boost.stacktrace.basic; +#if defined(BOOST_STACKTRACE_USE_STD_MODULE) +import std; +#endif + import boost.stacktrace.dump; #ifdef __clang__ diff --git a/modules/boost_stacktrace_dump.cppm b/modules/boost_stacktrace_dump.cppm index ae666d13..bba020c0 100644 --- a/modules/boost_stacktrace_dump.cppm +++ b/modules/boost_stacktrace_dump.cppm @@ -10,9 +10,12 @@ module; #include #include +#if !defined(BOOST_STACKTRACE_USE_STD_MODULE) +#include +#endif + #include #include -#include #include #define BOOST_STACKTRACE_INTERFACE_UNIT @@ -24,6 +27,10 @@ module; export module boost.stacktrace.dump; +#if defined(BOOST_STACKTRACE_USE_STD_MODULE) +import std; +#endif + #ifdef __clang__ # pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" #endif diff --git a/modules/boost_stacktrace_noop.cppm b/modules/boost_stacktrace_noop.cppm index 050251db..633612a1 100644 --- a/modules/boost_stacktrace_noop.cppm +++ b/modules/boost_stacktrace_noop.cppm @@ -9,14 +9,20 @@ module; #include +#if !defined(BOOST_STACKTRACE_USE_STD_MODULE) #include #include +#endif #define BOOST_STACKTRACE_INTERFACE_UNIT #define BOOST_STACKTRACE_LINK export module boost.stacktrace.noop; +#if defined(BOOST_STACKTRACE_USE_STD_MODULE) +import std; +#endif + #ifdef __clang__ # pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" #endif diff --git a/modules/samples/usage_sample_from_exception.cpp b/modules/samples/usage_sample_from_exception.cpp index 5cac1f2a..9461a326 100644 --- a/modules/samples/usage_sample_from_exception.cpp +++ b/modules/samples/usage_sample_from_exception.cpp @@ -6,7 +6,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include #include @@ -15,7 +15,8 @@ namespace { BOOST_NOINLINE void foo() { - throw std::logic_error{"Foo"}; + std::map m; + m.at(1); } BOOST_NOINLINE void bar() { From f9ecb7ade6b1478a5b70e29f78e320b780e09b77 Mon Sep 17 00:00:00 2001 From: Fedor Osetrov Date: Sun, 29 Mar 2026 11:48:40 +0000 Subject: [PATCH 2/9] add import std CI --- .github/workflows/ci.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 659a4383..82aec04d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,10 +94,28 @@ jobs: make -j"$(nproc)" make install + - name: Run modules tests + if: ${{matrix.toolset == 'clang-19'}} + run: | + cd ../boost-root/libs/$LIBRARY + cmake -S test/cmake_subdir_test \ + -B build_module \ + -GNinja \ + -DBOOST_USE_MODULES=1 \ + -DBUILD_TESTING=1 \ + -DCMAKE_CXX_STANDARD=23 \ + -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ + -DCMAKE_CXX_FLAGS="-stdlib=libc++ -I/home/runner/.local/include" \ + -DCMAKE_EXE_LINKER_FLAGS="-L/home/runner/.local" \ + -DCMAKE_CXX_MODULE_STD=ON \ + -DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=0e5b6991-d74f-4b3d-a41c-cf096e0b2508 + cmake --build build_module + ctest --test-dir build_module -VV + rm -rf build_module + - name: Run modules tests without 'import std;' if: ${{matrix.toolset == 'clang-19'}} run: | - pwd cd ../boost-root/libs/$LIBRARY cmake -S test/cmake_subdir_test \ -B build_module \ From b140f0bc54e71c799ad57a8ad7c2ff25c752c11e Mon Sep 17 00:00:00 2001 From: Fedor Osetrov Date: Sun, 29 Mar 2026 12:02:48 +0000 Subject: [PATCH 3/9] try fix noop module --- modules/boost_stacktrace_noop.cppm | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/boost_stacktrace_noop.cppm b/modules/boost_stacktrace_noop.cppm index 633612a1..3519d955 100644 --- a/modules/boost_stacktrace_noop.cppm +++ b/modules/boost_stacktrace_noop.cppm @@ -8,6 +8,7 @@ module; #include +#include #if !defined(BOOST_STACKTRACE_USE_STD_MODULE) #include From 801cad4339f1d50996070ef8b63fbc1de4dee561 Mon Sep 17 00:00:00 2001 From: Fedor Osetrov Date: Sat, 11 Apr 2026 14:52:33 +0000 Subject: [PATCH 4/9] fix build --- include/boost/stacktrace/safe_dump_to.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/boost/stacktrace/safe_dump_to.hpp b/include/boost/stacktrace/safe_dump_to.hpp index 7e2566b9..2947c85e 100644 --- a/include/boost/stacktrace/safe_dump_to.hpp +++ b/include/boost/stacktrace/safe_dump_to.hpp @@ -19,9 +19,11 @@ # pragma once #endif -#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) && !defined(BOOST_STACKTRACE_USE_STD_MODULE) +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) + +#if !defined(BOOST_STACKTRACE_USE_STD_MODULE) #include -#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) && !defined(BOOST_STACKTRACE_USE_STD_MODULE) +#endif // !defined(BOOST_STACKTRACE_USE_STD_MODULE) #if defined(BOOST_WINDOWS) #include From aa8294a905538839ab677f016843e8f49ba577d8 Mon Sep 17 00:00:00 2001 From: Fedor Osetrov Date: Sat, 2 May 2026 07:37:06 +0000 Subject: [PATCH 5/9] use env --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c677720..5a7e5deb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,8 +105,8 @@ jobs: -DBUILD_TESTING=1 \ -DCMAKE_CXX_STANDARD=23 \ -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ - -DCMAKE_CXX_FLAGS="-stdlib=libc++ -I/home/runner/.local/include" \ - -DCMAKE_EXE_LINKER_FLAGS="-L/home/runner/.local" \ + -DCMAKE_CXX_FLAGS="-stdlib=libc++ -I$HOME/.local/include" \ + -DCMAKE_EXE_LINKER_FLAGS="-L$HOME/.local" \ -DCMAKE_CXX_MODULE_STD=ON \ -DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=0e5b6991-d74f-4b3d-a41c-cf096e0b2508 cmake --build build_module From 88c70019b465c51b51a8eef7c07141fbffc8f80c Mon Sep 17 00:00:00 2001 From: Fedor Osetrov Date: Sat, 2 May 2026 07:49:05 +0000 Subject: [PATCH 6/9] better check --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 00d50733..87318c80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,7 +136,7 @@ else() endif() if(BOOST_USE_MODULES) - if (CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD AND CMAKE_CXX_MODULE_STD) + if ((CMAKE_CXX_STANDARD IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD) AND CMAKE_CXX_MODULE_STD) message(STATUS "Using `import std;`") set(__import_std ON) else() From 3291c638ffb62ae2ab23ef757bb9676a34ce0db4 Mon Sep 17 00:00:00 2001 From: Fedor Osetrov Date: Sat, 2 May 2026 07:53:02 +0000 Subject: [PATCH 7/9] fix warning --- modules/samples/usage_sample_from_exception.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/samples/usage_sample_from_exception.cpp b/modules/samples/usage_sample_from_exception.cpp index 9461a326..832e8796 100644 --- a/modules/samples/usage_sample_from_exception.cpp +++ b/modules/samples/usage_sample_from_exception.cpp @@ -16,7 +16,7 @@ namespace { BOOST_NOINLINE void foo() { std::map m; - m.at(1); + std::ignore = m.at(1); } BOOST_NOINLINE void bar() { From f966b6a1e63d1fbdaef2f8e65db5e0235547bef9 Mon Sep 17 00:00:00 2001 From: Fedor Osetrov <33493672+fdr400@users.noreply.github.com> Date: Tue, 5 May 2026 20:29:10 +0300 Subject: [PATCH 8/9] feat boost.stacktrace: C++20 modules support (#230) - Introduce `boost.stacktrace_dump` module for safe_dump interface - Introduce `boost.stacktrace_` module for each unwind/collect implementation method - Introduce `boost.stacktrace` module exposing best available backend implementation Also many tests was added for checking all available backend build and also header only library version Moreover, there are some checks for `Boost::stacktrace_` and `Boost::stacktrace_from_exception` compatibility --------- Co-authored-by: Fedor Osetrov --- .github/workflows/ci.yml | 57 ++++++++++++++-- .gitignore | 3 + CMakeLists.txt | 67 ++++++++++++++----- include/boost/stacktrace.hpp | 7 +- .../stacktrace/detail/addr2line_impls.hpp | 11 +-- include/boost/stacktrace/detail/addr_base.hpp | 2 + .../stacktrace/detail/addr_base_msvc.hpp | 2 + .../stacktrace/detail/backend_config.hpp | 24 +++++++ .../boost/stacktrace/detail/collect_msvc.ipp | 6 +- .../stacktrace/detail/collect_unwind.ipp | 6 +- include/boost/stacktrace/detail/config.hpp | 26 +++++++ .../boost/stacktrace/detail/frame_decl.hpp | 19 +++++- .../boost/stacktrace/detail/frame_msvc.ipp | 19 +++--- .../boost/stacktrace/detail/frame_unwind.ipp | 9 ++- .../stacktrace/detail/libbacktrace_impls.hpp | 9 ++- .../detail/location_from_symbol.hpp | 3 + .../stacktrace/detail/safe_dump_posix.ipp | 5 +- .../boost/stacktrace/detail/safe_dump_win.ipp | 6 +- .../boost/stacktrace/detail/to_dec_array.hpp | 2 + .../boost/stacktrace/detail/to_hex_array.hpp | 2 + .../stacktrace/detail/try_dec_convert.hpp | 2 + .../boost/stacktrace/detail/void_ptr_cast.hpp | 4 +- include/boost/stacktrace/frame.hpp | 12 +++- include/boost/stacktrace/safe_dump_to.hpp | 23 ++++++- include/boost/stacktrace/stacktrace.hpp | 20 +++++- include/boost/stacktrace/stacktrace_fwd.hpp | 11 +++ include/boost/stacktrace/this_thread.hpp | 11 ++- modules/boost_stacktrace.cppm | 9 +++ modules/boost_stacktrace_addr2line.cppm | 49 ++++++++++++++ modules/boost_stacktrace_backtrace.cppm | 47 +++++++++++++ modules/boost_stacktrace_basic.cppm | 44 ++++++++++++ modules/boost_stacktrace_dump.cppm | 45 +++++++++++++ modules/boost_stacktrace_noop.cppm | 33 +++++++++ modules/boost_stacktrace_windbg.cppm | 29 ++++++++ modules/boost_stacktrace_windbg_cached.cppm | 30 +++++++++ modules/samples/usage_sample.cpp | 34 ++++++++++ .../samples/usage_sample_from_exception.cpp | 34 ++++++++++ test/cmake_subdir_test/CMakeLists.txt | 46 ++++++++++--- test/cmake_subdir_test/main.cpp | 2 +- test/test.cpp | 5 +- test/test_from_exception.cpp | 4 +- test/test_from_exception_none.cpp | 4 +- test/test_torture.cpp | 2 +- test/test_trivial.cpp | 4 +- test/test_void_ptr_cast.cpp | 4 +- 45 files changed, 709 insertions(+), 84 deletions(-) create mode 100644 .gitignore create mode 100644 include/boost/stacktrace/detail/backend_config.hpp create mode 100644 include/boost/stacktrace/detail/config.hpp create mode 100644 modules/boost_stacktrace.cppm create mode 100644 modules/boost_stacktrace_addr2line.cppm create mode 100644 modules/boost_stacktrace_backtrace.cppm create mode 100644 modules/boost_stacktrace_basic.cppm create mode 100644 modules/boost_stacktrace_dump.cppm create mode 100644 modules/boost_stacktrace_noop.cppm create mode 100644 modules/boost_stacktrace_windbg.cppm create mode 100644 modules/boost_stacktrace_windbg_cached.cppm create mode 100644 modules/samples/usage_sample.cpp create mode 100644 modules/samples/usage_sample_from_exception.cpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe74c890..79eec1e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,10 +27,21 @@ jobs: - toolset: gcc-9 cxxstd: "03,11,14,17,2a" os: ubuntu-22.04 - install: g++-9 + install: [g++-9] - toolset: clang-15 cxxstd: "03,11,14,17,2a" os: ubuntu-22.04 + - toolset: clang-19 + compiler: clang++-19 + cxxstd: "20" + os: ubuntu-24.04 + install: &cxx19 + - clang-19 + - llvm-19 + - libclang-rt-19-dev + - libc++-19-dev + - libc++abi-19-dev + - clang-tools-19 # TODO: fix and uncomment #- toolset: clang # cxxstd: "03,11,14,17,2a" @@ -45,7 +56,7 @@ jobs: - name: Install packages if: matrix.install - run: sudo apt install ${{matrix.install}} + run: sudo apt install -y ${{join(matrix.install, ' ')}} - name: Setup Boost run: | @@ -71,6 +82,35 @@ jobs: ./bootstrap.sh ./b2 -d0 headers ./b2 -j4 variant=debug tools/inspect + + - name: Build libbacktrace + if: ${{matrix.toolset == 'clang-19'}} + run: | + # libc++ do not have bundled libbacktrace implementation + git clone --depth=1 https://github.com/ianlancetaylor/libbacktrace.git + cd libbacktrace + CC=clang-19 OBJCOPY=/usr/bin/llvm-objcopy NM=/usr/bin/llvm-nm \ + ./configure --prefix="$HOME/.local" --with-system-libunwind + make -j"$(nproc)" + make install + + - name: Run modules tests without 'import std;' + if: ${{matrix.toolset == 'clang-19'}} + run: | + pwd + cd ../boost-root/libs/$LIBRARY + cmake -S test/cmake_subdir_test \ + -B build_module \ + -GNinja \ + -DBOOST_USE_MODULES=1 \ + -DBUILD_TESTING=1 \ + -DCMAKE_CXX_STANDARD=20 \ + -DCMAKE_CXX_COMPILER=${{matrix.compiler}} \ + -DCMAKE_CXX_FLAGS="-stdlib=libc++ -I$HOME/.local/include" \ + -DCMAKE_EXE_LINKER_FLAGS="-L$HOME/.local" + cmake --build build_module + ctest --test-dir build_module -VV + rm -rf build_module - name: Run tests run: | @@ -205,11 +245,14 @@ jobs: - name: Use library with add_subdirectory run: | - cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test - mkdir __build__ && cd __build__ - cmake -DBUILD_SHARED_LIBS=${{matrix.shared}} .. - cmake --build . - ctest --output-on-failure --no-tests=error + cd ../boost-root/libs/$LIBRARY + cmake -S test/cmake_subdir_test -B __build__ \ + -GNinja \ + -DBUILD_SHARED_LIBS=${{matrix.shared}} + + cmake --build __build__ + ctest --test-dir __build__ --output-on-failure --no-tests=error + rm -rf __build__ posix-cmake-install: strategy: diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a77efcd9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build?* +.cache +.vscode diff --git a/CMakeLists.txt b/CMakeLists.txt index d642defe..36c97e50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,18 @@ cmake_minimum_required(VERSION 3.8...4.20) project(boost_stacktrace VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) -function(stacktrace_add_library suffix opt public_libs libs defs) +function(stacktrace_add_module name) + target_sources(${name} + PUBLIC + FILE_SET CXX_MODULES + BASE_DIRS "${CMAKE_CURRENT_LIST_DIR}/modules" + FILES "${CMAKE_CURRENT_LIST_DIR}/modules/${name}.cppm" + ) + target_compile_features(${name} PUBLIC cxx_std_20) + target_compile_definitions(${name} PUBLIC BOOST_USE_MODULES) +endfunction() + +function(stacktrace_add_library suffix opt public_libs libs defs add_module) if(NOT opt) return() @@ -38,10 +49,14 @@ function(stacktrace_add_library suffix opt public_libs libs defs) ${defs} ) - target_sources(boost_stacktrace_${suffix} - PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/src/${suffix}.cpp - ) + if (add_module) + stacktrace_add_module(boost_stacktrace_${suffix}) + else() + target_sources(boost_stacktrace_${suffix} + PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/src/${suffix}.cpp" + ) + endif() if(BUILD_SHARED_LIBS) target_compile_definitions(boost_stacktrace_${suffix} PUBLIC BOOST_STACKTRACE_DYN_LINK) @@ -110,24 +125,40 @@ if(BOOST_STACKTRACE_ENABLE_BACKTRACE OR BOOST_STACKTRACE_ENABLE_WINDBG_CACHED ) set(_enable_non_noop_backend TRUE) +else() + set(_enable_non_noop_backend FALSE) endif() -if(_enable_non_noop_backend) - stacktrace_add_library(dump ON "" "" "") +if(NOT BOOST_USE_MODULES) + set(BOOST_USE_MODULES OFF) endif() -stacktrace_add_library(noop ${BOOST_STACKTRACE_ENABLE_NOOP} "" "" "") -stacktrace_add_library(backtrace ${BOOST_STACKTRACE_ENABLE_BACKTRACE} Boost::stacktrace_dump "backtrace;${CMAKE_DL_LIBS}" "") -stacktrace_add_library(addr2line ${BOOST_STACKTRACE_ENABLE_ADDR2LINE} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "") -stacktrace_add_library(basic ${BOOST_STACKTRACE_ENABLE_BASIC} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "") -stacktrace_add_library(windbg ${BOOST_STACKTRACE_ENABLE_WINDBG} Boost::stacktrace_dump "dbgeng;ole32" "_GNU_SOURCE=1") -stacktrace_add_library(windbg_cached ${BOOST_STACKTRACE_ENABLE_WINDBG_CACHED} Boost::stacktrace_dump "dbgeng;ole32" "_GNU_SOURCE=1") + +stacktrace_add_library(dump ${_enable_non_noop_backend} "" "" "" ${BOOST_USE_MODULES}) +stacktrace_add_library(noop ${BOOST_STACKTRACE_ENABLE_NOOP} "" "" "" ${BOOST_USE_MODULES}) +stacktrace_add_library(backtrace ${BOOST_STACKTRACE_ENABLE_BACKTRACE} Boost::stacktrace_dump "backtrace;${CMAKE_DL_LIBS}" "" ${BOOST_USE_MODULES}) +stacktrace_add_library(addr2line ${BOOST_STACKTRACE_ENABLE_ADDR2LINE} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "" ${BOOST_USE_MODULES}) +stacktrace_add_library(basic ${BOOST_STACKTRACE_ENABLE_BASIC} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "" ${BOOST_USE_MODULES}) +stacktrace_add_library(windbg ${BOOST_STACKTRACE_ENABLE_WINDBG} Boost::stacktrace_dump "dbgeng;ole32" "_GNU_SOURCE=1" ${BOOST_USE_MODULES}) +stacktrace_add_library(windbg_cached ${BOOST_STACKTRACE_ENABLE_WINDBG_CACHED} Boost::stacktrace_dump "dbgeng;ole32" "_GNU_SOURCE=1" ${BOOST_USE_MODULES}) # boost_stacktrace, default library -add_library(boost_stacktrace INTERFACE) +if(BOOST_USE_MODULES) + add_library(boost_stacktrace) + stacktrace_add_module(boost_stacktrace boost_stacktrace) + set(__scope PUBLIC) -target_include_directories(boost_stacktrace INTERFACE include) + foreach(backend noop backtrace addr2line basic windbg windbg_cached) + if (TARGET boost_stacktrace_${backend}) + target_compile_definitions(boost_stacktrace_${backend} INTERFACE BOOST_STACKTRACE_BACKEND_MODULE=${backend}) + endif() + endforeach() +else() + add_library(boost_stacktrace INTERFACE) + set(__scope INTERFACE) +endif() +target_include_directories(boost_stacktrace ${__scope} "${CMAKE_CURRENT_LIST_DIR}/include") add_library(Boost::stacktrace ALIAS boost_stacktrace) if(BOOST_STACKTRACE_ENABLE_WINDBG) @@ -147,13 +178,13 @@ else() endif() message(STATUS "Boost.stacktrace default backend: ${__default_stacktrace_backend}") -target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_${__default_stacktrace_backend}) +target_link_libraries(boost_stacktrace ${__scope} Boost::stacktrace_${__default_stacktrace_backend}) # Boost::stacktrace_from_exception is never the default if(_enable_non_noop_backend) - stacktrace_add_library(from_exception ${BOOST_STACKTRACE_ENABLE_FROM_EXCEPTION} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "") - unset(_enable_non_noop_backend) + stacktrace_add_library(from_exception ${BOOST_STACKTRACE_ENABLE_FROM_EXCEPTION} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "" FALSE) endif() +unset(_enable_non_noop_backend) if(BUILD_TESTING) add_subdirectory(test) diff --git a/include/boost/stacktrace.hpp b/include/boost/stacktrace.hpp index 697102dc..036c3c0d 100644 --- a/include/boost/stacktrace.hpp +++ b/include/boost/stacktrace.hpp @@ -7,7 +7,10 @@ #ifndef BOOST_STACKTRACE_HPP #define BOOST_STACKTRACE_HPP -#include +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #ifdef BOOST_HAS_PRAGMA_ONCE # pragma once #endif @@ -17,4 +20,6 @@ #include #include +#endif // !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #endif // BOOST_STACKTRACE_HPP diff --git a/include/boost/stacktrace/detail/addr2line_impls.hpp b/include/boost/stacktrace/detail/addr2line_impls.hpp index 255ea7f6..f2e3b293 100644 --- a/include/boost/stacktrace/detail/addr2line_impls.hpp +++ b/include/boost/stacktrace/detail/addr2line_impls.hpp @@ -12,18 +12,21 @@ # pragma once #endif -#include -#include -#include -#include +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include + #include #include #include #include #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) +#include +#include +#include +#include namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/addr_base.hpp b/include/boost/stacktrace/detail/addr_base.hpp index b16ac2ba..5df86bcb 100644 --- a/include/boost/stacktrace/detail/addr_base.hpp +++ b/include/boost/stacktrace/detail/addr_base.hpp @@ -12,10 +12,12 @@ # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #include #include #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/addr_base_msvc.hpp b/include/boost/stacktrace/detail/addr_base_msvc.hpp index 7d429871..34959131 100644 --- a/include/boost/stacktrace/detail/addr_base_msvc.hpp +++ b/include/boost/stacktrace/detail/addr_base_msvc.hpp @@ -12,6 +12,7 @@ # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #include #include @@ -27,6 +28,7 @@ #include #undef WIN32_LEAN_AND_MEAN #endif +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) namespace boost { namespace stacktrace { namespace detail { inline std::uintptr_t get_own_proc_addr_base(const void* addr) { diff --git a/include/boost/stacktrace/detail/backend_config.hpp b/include/boost/stacktrace/detail/backend_config.hpp new file mode 100644 index 00000000..9e27eb60 --- /dev/null +++ b/include/boost/stacktrace/detail/backend_config.hpp @@ -0,0 +1,24 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_STACKTRACE_DETAIL_BACKEND_CONFIG_HPP +#define BOOST_STACKTRACE_DETAIL_BACKEND_CONFIG_HPP + +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) +# include +# ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +# endif +#endif + +#include "boost/stacktrace/detail/config.hpp" + +#if defined(BOOST_USE_MODULES) && !defined(BOOST_STACKTRACE_INTERFACE_UNIT) && !defined(BOOST_STACKTRACE_INTERNAL_BUILD_LIBS) + import boost.stacktrace.BOOST_STACKTRACE_BACKEND_MODULE; +#endif + +#endif diff --git a/include/boost/stacktrace/detail/collect_msvc.ipp b/include/boost/stacktrace/detail/collect_msvc.ipp index 879d9d74..353a85d1 100644 --- a/include/boost/stacktrace/detail/collect_msvc.ipp +++ b/include/boost/stacktrace/detail/collect_msvc.ipp @@ -12,9 +12,11 @@ # pragma once #endif -#include - +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) + +#include namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/collect_unwind.ipp b/include/boost/stacktrace/detail/collect_unwind.ipp index b738e62e..7fcae4f7 100644 --- a/include/boost/stacktrace/detail/collect_unwind.ipp +++ b/include/boost/stacktrace/detail/collect_unwind.ipp @@ -12,8 +12,7 @@ # pragma once #endif -#include - +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) // On iOS 32-bit ARM architecture _Unwind_Backtrace function doesn't exist, symbol is undefined. // Forcing libc backtrace() function usage. #include @@ -28,11 +27,14 @@ #include #endif #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #if !defined(_GNU_SOURCE) && !defined(BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED) && !defined(BOOST_WINDOWS) #error "Boost.Stacktrace requires `_Unwind_Backtrace` function. Define `_GNU_SOURCE` macro or `BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED` if _Unwind_Backtrace is available without `_GNU_SOURCE`." #endif +#include + namespace boost { namespace stacktrace { namespace detail { #if !defined(BOOST_STACKTRACE_USE_LIBC_BACKTRACE_FUNCTION) diff --git a/include/boost/stacktrace/detail/config.hpp b/include/boost/stacktrace/detail/config.hpp new file mode 100644 index 00000000..031fb629 --- /dev/null +++ b/include/boost/stacktrace/detail/config.hpp @@ -0,0 +1,26 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_STACKTRACE_DETAIL_CONFIG_HPP +#define BOOST_STACKTRACE_DETAIL_CONFIG_HPP + +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) +# include +# ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +# endif +#endif + +#ifdef BOOST_STACKTRACE_INTERFACE_UNIT +# define BOOST_STACKTRACE_BEGIN_MODULE_EXPORT export { +# define BOOST_STACKTRACE_END_MODULE_EXPORT } +#else +# define BOOST_STACKTRACE_BEGIN_MODULE_EXPORT +# define BOOST_STACKTRACE_END_MODULE_EXPORT +#endif + +#endif diff --git a/include/boost/stacktrace/detail/frame_decl.hpp b/include/boost/stacktrace/detail/frame_decl.hpp index 8920e212..64eaf623 100644 --- a/include/boost/stacktrace/detail/frame_decl.hpp +++ b/include/boost/stacktrace/detail/frame_decl.hpp @@ -7,14 +7,22 @@ #ifndef BOOST_STACKTRACE_DETAIL_FRAME_DECL_HPP #define BOOST_STACKTRACE_DETAIL_FRAME_DECL_HPP -#include +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #ifdef BOOST_HAS_PRAGMA_ONCE # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) + +#if !defined(BOOST_USE_MODULES) +#include +#endif -#include // boost::stacktrace::detail::native_frame_ptr_t #include #include @@ -22,6 +30,8 @@ /// @file boost/stacktrace/detail/frame_decl.hpp /// Use header instead of this one! +BOOST_STACKTRACE_BEGIN_MODULE_EXPORT + namespace boost { namespace stacktrace { /// @class boost::stacktrace::frame boost/stacktrace/detail/frame_decl.hpp @@ -146,7 +156,10 @@ namespace detail { }} // namespace boost::stacktrace - #include +BOOST_STACKTRACE_END_MODULE_EXPORT + +#endif // !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #endif // BOOST_STACKTRACE_DETAIL_FRAME_DECL_HPP diff --git a/include/boost/stacktrace/detail/frame_msvc.ipp b/include/boost/stacktrace/detail/frame_msvc.ipp index 4d782761..12f5e09c 100644 --- a/include/boost/stacktrace/detail/frame_msvc.ipp +++ b/include/boost/stacktrace/detail/frame_msvc.ipp @@ -12,16 +12,9 @@ # pragma once #endif -#include - +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #include -#include -#include - -#ifndef BOOST_STACKTRACE_DISABLE_OFFSET_ADDR_BASE -#include -#endif #ifdef WIN32_LEAN_AND_MEAN #include @@ -36,6 +29,16 @@ #include "dbgeng.h" #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) + +#include + +#include +#include + +#ifndef BOOST_STACKTRACE_DISABLE_OFFSET_ADDR_BASE +#include +#endif #if defined(__clang__) || defined(BOOST_MSVC) # pragma comment(lib, "ole32.lib") diff --git a/include/boost/stacktrace/detail/frame_unwind.ipp b/include/boost/stacktrace/detail/frame_unwind.ipp index 5a7cbea1..40ad842f 100644 --- a/include/boost/stacktrace/detail/frame_unwind.ipp +++ b/include/boost/stacktrace/detail/frame_unwind.ipp @@ -12,15 +12,18 @@ # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) +#include + +#include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #include #include #include #include #include -#include - -#include #ifdef BOOST_STACKTRACE_USE_BACKTRACE # include diff --git a/include/boost/stacktrace/detail/libbacktrace_impls.hpp b/include/boost/stacktrace/detail/libbacktrace_impls.hpp index bde53f22..616bd820 100644 --- a/include/boost/stacktrace/detail/libbacktrace_impls.hpp +++ b/include/boost/stacktrace/detail/libbacktrace_impls.hpp @@ -12,9 +12,7 @@ # pragma once #endif -#include -#include -#include +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #ifdef BOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE @@ -22,6 +20,11 @@ #else # include #endif +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) + +#include +#include +#include namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/location_from_symbol.hpp b/include/boost/stacktrace/detail/location_from_symbol.hpp index ea88c3e6..9dbd5f6f 100644 --- a/include/boost/stacktrace/detail/location_from_symbol.hpp +++ b/include/boost/stacktrace/detail/location_from_symbol.hpp @@ -12,11 +12,13 @@ # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) # include #else # include #endif +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #ifdef _AIX /* AIX doesn't provide dladdr syscall. @@ -26,6 +28,7 @@ #include #include + #include #include #include diff --git a/include/boost/stacktrace/detail/safe_dump_posix.ipp b/include/boost/stacktrace/detail/safe_dump_posix.ipp index a5cc86ef..2ff13ac7 100644 --- a/include/boost/stacktrace/detail/safe_dump_posix.ipp +++ b/include/boost/stacktrace/detail/safe_dump_posix.ipp @@ -12,12 +12,13 @@ # pragma once #endif -#include - +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include // ::write #include // ::open #include // S_IWUSR and friends +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) +#include namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/safe_dump_win.ipp b/include/boost/stacktrace/detail/safe_dump_win.ipp index 9b998ce0..a8cf6c34 100644 --- a/include/boost/stacktrace/detail/safe_dump_win.ipp +++ b/include/boost/stacktrace/detail/safe_dump_win.ipp @@ -12,14 +12,16 @@ # pragma once #endif -#include - +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #include #include #include #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) + +#include namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/to_dec_array.hpp b/include/boost/stacktrace/detail/to_dec_array.hpp index dc5372e3..fdba1ba4 100644 --- a/include/boost/stacktrace/detail/to_dec_array.hpp +++ b/include/boost/stacktrace/detail/to_dec_array.hpp @@ -12,8 +12,10 @@ # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #include // std::size_t +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/to_hex_array.hpp b/include/boost/stacktrace/detail/to_hex_array.hpp index ee9a6b15..98c54e63 100644 --- a/include/boost/stacktrace/detail/to_hex_array.hpp +++ b/include/boost/stacktrace/detail/to_hex_array.hpp @@ -12,8 +12,10 @@ # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/try_dec_convert.hpp b/include/boost/stacktrace/detail/try_dec_convert.hpp index 4d5f2478..0f026549 100644 --- a/include/boost/stacktrace/detail/try_dec_convert.hpp +++ b/include/boost/stacktrace/detail/try_dec_convert.hpp @@ -12,7 +12,9 @@ # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) namespace boost { namespace stacktrace { namespace detail { diff --git a/include/boost/stacktrace/detail/void_ptr_cast.hpp b/include/boost/stacktrace/detail/void_ptr_cast.hpp index f275ecfb..9e83e9be 100644 --- a/include/boost/stacktrace/detail/void_ptr_cast.hpp +++ b/include/boost/stacktrace/detail/void_ptr_cast.hpp @@ -13,7 +13,9 @@ # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 301) # pragma GCC system_header @@ -22,7 +24,7 @@ namespace boost { namespace stacktrace { namespace detail { // GCC warns when reinterpret_cast between function pointer and object pointer occur. -// This functionsuppress the warnings and ensures that such casts are safe. +// This function suppress the warnings and ensures that such casts are safe. template To void_ptr_cast(From* v) noexcept { static_assert( diff --git a/include/boost/stacktrace/frame.hpp b/include/boost/stacktrace/frame.hpp index d14f8e7d..734eed81 100644 --- a/include/boost/stacktrace/frame.hpp +++ b/include/boost/stacktrace/frame.hpp @@ -7,13 +7,18 @@ #ifndef BOOST_STACKTRACE_FRAME_HPP #define BOOST_STACKTRACE_FRAME_HPP -#include +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #ifdef BOOST_HAS_PRAGMA_ONCE # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #include @@ -32,6 +37,8 @@ void* boost_stacktrace_impl_return_nullptr() { return nullptr; } } #endif +BOOST_STACKTRACE_BEGIN_MODULE_EXPORT + namespace boost { namespace stacktrace { /// Comparison operators that provide platform dependant ordering and have O(1) complexity; are Async-Handler-Safe. @@ -58,6 +65,8 @@ std::basic_ostream& operator<<(std::basic_ostream @@ -73,5 +82,6 @@ std::basic_ostream& operator<<(std::basic_ostream +#include + +#if defined(BOOST_USE_MODULES) && !defined(BOOST_STACKTRACE_INTERFACE_UNIT) + import boost.stacktrace.dump; +#endif + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #ifdef BOOST_HAS_PRAGMA_ONCE # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #if defined(BOOST_WINDOWS) #include #endif +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include @@ -35,7 +44,9 @@ namespace boost { namespace stacktrace { /// @cond namespace detail { +BOOST_STACKTRACE_BEGIN_MODULE_EXPORT using native_frame_ptr_t = const void*; +BOOST_STACKTRACE_END_MODULE_EXPORT enum helper{ max_frames_dump = 128 }; BOOST_STACKTRACE_FUNCTION std::size_t from_dump(const char* filename, native_frame_ptr_t* out_frames); @@ -48,6 +59,8 @@ namespace detail { #endif +BOOST_STACKTRACE_BEGIN_MODULE_EXPORT + struct this_thread_frames { // struct is required to avoid warning about usage of inline+BOOST_NOINLINE BOOST_NOINLINE BOOST_STACKTRACE_FUNCTION static std::size_t collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) noexcept; @@ -79,9 +92,13 @@ struct this_thread_frames { // struct is required to avoid warning about usage o } }; +BOOST_STACKTRACE_END_MODULE_EXPORT + } // namespace detail /// @endcond +BOOST_STACKTRACE_BEGIN_MODULE_EXPORT + /// @brief Stores current function call sequence into the memory. /// /// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined. @@ -199,6 +216,8 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_dep }} // namespace boost::stacktrace +BOOST_STACKTRACE_END_MODULE_EXPORT + #ifdef BOOST_INTEL # pragma warning(pop) #endif @@ -223,4 +242,6 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_dep # endif #endif +#endif // !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #endif // BOOST_STACKTRACE_SAFE_DUMP_TO_HPP diff --git a/include/boost/stacktrace/stacktrace.hpp b/include/boost/stacktrace/stacktrace.hpp index f0000dd5..6070a405 100644 --- a/include/boost/stacktrace/stacktrace.hpp +++ b/include/boost/stacktrace/stacktrace.hpp @@ -7,11 +7,15 @@ #ifndef BOOST_STACKTRACE_STACKTRACE_HPP #define BOOST_STACKTRACE_STACKTRACE_HPP -#include +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #ifdef BOOST_HAS_PRAGMA_ONCE # pragma once #endif +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #include @@ -22,9 +26,9 @@ #ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS # include #endif +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include -#include #include #include @@ -58,9 +62,15 @@ namespace impl { #if defined(__GNUC__) && defined(__ELF__) +#if defined(BOOST_USE_MODULES) +extern "C++" +#endif BOOST_NOINLINE BOOST_SYMBOL_VISIBLE __attribute__((weak)) const char* current_exception_stacktrace() noexcept; +#if defined(BOOST_USE_MODULES) +extern "C++" +#endif BOOST_NOINLINE BOOST_SYMBOL_VISIBLE __attribute__((weak)) bool& ref_capture_stacktraces_at_throw() noexcept; @@ -68,6 +78,8 @@ bool& ref_capture_stacktraces_at_throw() noexcept; } // namespace impl +BOOST_STACKTRACE_BEGIN_MODULE_EXPORT + /// Class that on construction copies minimal information about call stack into its internals and provides access to that information. /// @tparam Allocator Allocator to use during stack capture. template @@ -482,10 +494,14 @@ std::basic_ostream& operator<<(std::basic_ostream stacktrace; +BOOST_STACKTRACE_END_MODULE_EXPORT + }} // namespace boost::stacktrace #ifdef BOOST_INTEL # pragma warning(pop) #endif +#endif // !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #endif // BOOST_STACKTRACE_STACKTRACE_HPP diff --git a/include/boost/stacktrace/stacktrace_fwd.hpp b/include/boost/stacktrace/stacktrace_fwd.hpp index 6b0ee28d..764591b7 100644 --- a/include/boost/stacktrace/stacktrace_fwd.hpp +++ b/include/boost/stacktrace/stacktrace_fwd.hpp @@ -7,13 +7,21 @@ #ifndef BOOST_STACKTRACE_STACKTRACE_FWD_HPP #define BOOST_STACKTRACE_STACKTRACE_FWD_HPP +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + +#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) #include #include +#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) /// @file stacktrace_fwd.hpp This header contains only forward declarations of /// boost::stacktrace::frame, boost::stacktrace::basic_stacktrace, boost::stacktrace::stacktrace /// and does not include any other Boost headers. +BOOST_STACKTRACE_BEGIN_MODULE_EXPORT + /// @cond namespace boost { namespace stacktrace { @@ -24,5 +32,8 @@ typedef basic_stacktrace<> stacktrace; }} // namespace boost::stacktrace /// @endcond +BOOST_STACKTRACE_END_MODULE_EXPORT + +#endif // !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) #endif // BOOST_STACKTRACE_STACKTRACE_FWD_HPP diff --git a/include/boost/stacktrace/this_thread.hpp b/include/boost/stacktrace/this_thread.hpp index 6b4f9daa..29dbc4ce 100644 --- a/include/boost/stacktrace/this_thread.hpp +++ b/include/boost/stacktrace/this_thread.hpp @@ -7,13 +7,18 @@ #ifndef BOOST_STACKTRACE_THIS_THREAD_HPP #define BOOST_STACKTRACE_THIS_THREAD_HPP -#include +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #ifdef BOOST_HAS_PRAGMA_ONCE # pragma once #endif #include +BOOST_STACKTRACE_BEGIN_MODULE_EXPORT + namespace boost { namespace stacktrace { namespace this_thread { /// @brief Invoking the function with the enable parameter equal to `true` @@ -59,4 +64,8 @@ inline bool get_capture_stacktraces_at_throw() noexcept { }}} // namespace boost::stacktrace::this_thread +BOOST_STACKTRACE_END_MODULE_EXPORT + +#endif // !defined(BOOST_USE_MODULES) || defined(BOOST_STACKTRACE_INTERFACE_UNIT) + #endif // BOOST_STACKTRACE_THIS_THREAD_HPP diff --git a/modules/boost_stacktrace.cppm b/modules/boost_stacktrace.cppm new file mode 100644 index 00000000..35cfe4b1 --- /dev/null +++ b/modules/boost_stacktrace.cppm @@ -0,0 +1,9 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +export module boost.stacktrace; +export import boost.stacktrace.BOOST_STACKTRACE_BACKEND_MODULE; diff --git a/modules/boost_stacktrace_addr2line.cppm b/modules/boost_stacktrace_addr2line.cppm new file mode 100644 index 00000000..c331c9c6 --- /dev/null +++ b/modules/boost_stacktrace_addr2line.cppm @@ -0,0 +1,49 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module; + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define BOOST_STACKTRACE_INTERFACE_UNIT +#define BOOST_STACKTRACE_LINK + +export module boost.stacktrace.addr2line; + +import boost.stacktrace.dump; + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#endif + +#include +#include + +module :private; +#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS +#define BOOST_STACKTRACE_USE_ADDR2LINE +#include diff --git a/modules/boost_stacktrace_backtrace.cppm b/modules/boost_stacktrace_backtrace.cppm new file mode 100644 index 00000000..ae95d564 --- /dev/null +++ b/modules/boost_stacktrace_backtrace.cppm @@ -0,0 +1,47 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module; + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#define BOOST_STACKTRACE_INTERFACE_UNIT +#define BOOST_STACKTRACE_LINK + +export module boost.stacktrace.backtrace; + +import boost.stacktrace.dump; + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#endif + +#include +#include + +module :private; +#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS +#define BOOST_STACKTRACE_USE_BACKTRACE +#include diff --git a/modules/boost_stacktrace_basic.cppm b/modules/boost_stacktrace_basic.cppm new file mode 100644 index 00000000..ae3a22e1 --- /dev/null +++ b/modules/boost_stacktrace_basic.cppm @@ -0,0 +1,44 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module; + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define BOOST_STACKTRACE_INTERFACE_UNIT +#define BOOST_STACKTRACE_LINK + +export module boost.stacktrace.basic; + +import boost.stacktrace.dump; + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#endif + +#include +#include + +module :private; +#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS +#include diff --git a/modules/boost_stacktrace_dump.cppm b/modules/boost_stacktrace_dump.cppm new file mode 100644 index 00000000..b9762769 --- /dev/null +++ b/modules/boost_stacktrace_dump.cppm @@ -0,0 +1,45 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module; + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include +#include + +#include +#include +#include +#include + +#define BOOST_STACKTRACE_INTERFACE_UNIT +#define BOOST_STACKTRACE_LINK + +export module boost.stacktrace.dump; + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#endif + +#include + +module :private; +#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS +#if defined(BOOST_WINDOWS) +# include +#else +# include +#endif +#if defined(BOOST_WINDOWS) && !defined(BOOST_WINAPI_IS_MINGW) // MinGW does not provide RtlCaptureStackBackTrace. MinGW-w64 does. +# include +#else +# include +#endif + diff --git a/modules/boost_stacktrace_noop.cppm b/modules/boost_stacktrace_noop.cppm new file mode 100644 index 00000000..80ef6f06 --- /dev/null +++ b/modules/boost_stacktrace_noop.cppm @@ -0,0 +1,33 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module; + +#include +#include +#include + +#include +#include + +#define BOOST_STACKTRACE_INTERFACE_UNIT +#define BOOST_STACKTRACE_LINK + +export module boost.stacktrace.noop; + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#endif + +#include +#include + +module :private; +#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS +#include +#include +#include diff --git a/modules/boost_stacktrace_windbg.cppm b/modules/boost_stacktrace_windbg.cppm new file mode 100644 index 00000000..af537442 --- /dev/null +++ b/modules/boost_stacktrace_windbg.cppm @@ -0,0 +1,29 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module; + +#include +#include +#include +#include +#include +#include + +#define BOOST_STACKTRACE_INTERFACE_UNIT +#define BOOST_STACKTRACE_LINK + +export module boost.stacktrace.windbg; + +import boost.stacktrace.dump; + +#include +#include + +module :private; +#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS +#include diff --git a/modules/boost_stacktrace_windbg_cached.cppm b/modules/boost_stacktrace_windbg_cached.cppm new file mode 100644 index 00000000..fb374a2e --- /dev/null +++ b/modules/boost_stacktrace_windbg_cached.cppm @@ -0,0 +1,30 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module; + +#include +#include +#include +#include +#include +#include + +#define BOOST_STACKTRACE_INTERFACE_UNIT +#define BOOST_STACKTRACE_LINK + +export module boost.stacktrace.windbg; + +import boost.stacktrace.dump; + +#include +#include + +module :private; +#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS +#define BOOST_STACKTRACE_USE_WINDBG_CACHED +#include diff --git a/modules/samples/usage_sample.cpp b/modules/samples/usage_sample.cpp new file mode 100644 index 00000000..d3ef2bee --- /dev/null +++ b/modules/samples/usage_sample.cpp @@ -0,0 +1,34 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +#if defined(STACKTRACE_MODULE) +import STACKTRACE_MODULE; +#else +import boost.stacktrace; +#endif + +namespace { + +BOOST_NOINLINE void foo() { + auto trace = boost::stacktrace::stacktrace{}; + std::cerr << trace; +} + +BOOST_NOINLINE void bar() { + foo(); +} + +} + +int main() { + bar(); + + return 0; +} diff --git a/modules/samples/usage_sample_from_exception.cpp b/modules/samples/usage_sample_from_exception.cpp new file mode 100644 index 00000000..5cac1f2a --- /dev/null +++ b/modules/samples/usage_sample_from_exception.cpp @@ -0,0 +1,34 @@ +// Copyright Antony Polukhin, 2025-2026. +// Copyright Fedor Osetrov, 2025-2026. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +#include + +#include + +namespace { + +BOOST_NOINLINE void foo() { + throw std::logic_error{"Foo"}; +} + +BOOST_NOINLINE void bar() { + foo(); +} + +} + +int main() { + try { + bar(); + } catch (const std::exception& ex) { + const auto trace = boost::stacktrace::stacktrace::from_current_exception(); + std::cerr << "Exception: " << ex.what() << ", trace:\n" << trace << '\n'; + } +} diff --git a/test/cmake_subdir_test/CMakeLists.txt b/test/cmake_subdir_test/CMakeLists.txt index b852a471..049a5572 100644 --- a/test/cmake_subdir_test/CMakeLists.txt +++ b/test/cmake_subdir_test/CMakeLists.txt @@ -40,13 +40,39 @@ endforeach() enable_testing() add_subdirectory(../.. boostorg/stacktrace) -add_executable(main main.cpp) -target_link_libraries(main Boost::stacktrace) - -add_executable(main_header_only main.cpp) -target_include_directories(main_header_only PRIVATE ../../include) -target_compile_definitions(main_header_only PRIVATE "_GNU_SOURCE=1") -target_link_libraries(main_header_only PRIVATE Boost::core Boost::container_hash Boost::predef Boost::winapi) - -add_test(NAME main COMMAND main) -add_test(NAME main_header_only COMMAND main_header_only) +add_executable(stacktrace_main main.cpp) +target_link_libraries(stacktrace_main Boost::stacktrace) + +add_executable(stacktrace_main_header_only main.cpp) +target_include_directories(stacktrace_main_header_only PRIVATE ../../include) +target_compile_definitions(stacktrace_main_header_only PRIVATE "_GNU_SOURCE=1") +target_link_libraries(stacktrace_main_header_only PRIVATE Boost::core Boost::container_hash Boost::predef Boost::winapi) + +add_test(NAME stacktrace_main COMMAND stacktrace_main) +add_test(NAME stacktrace_main_header_only COMMAND stacktrace_main_header_only) + +if (BOOST_USE_MODULES) + add_executable(boost_stacktrace_module_usage ../../modules/samples/usage_sample.cpp) + target_link_libraries(boost_stacktrace_module_usage PRIVATE Boost::stacktrace) + add_test(NAME boost_stacktrace_module_usage COMMAND boost_stacktrace_module_usage) + + add_executable(boost_stacktrace_from_exception_module_usage ../../modules/samples/usage_sample_from_exception.cpp) + target_link_libraries(boost_stacktrace_from_exception_module_usage PRIVATE Boost::stacktrace Boost::stacktrace_from_exception) + add_test(NAME boost_stacktrace_from_exception_module_usage COMMAND boost_stacktrace_from_exception_module_usage) + + foreach(backend noop basic addr2line backtrace) + if (NOT TARGET Boost::stacktrace_${backend}) + message(STATUS "Skipping ${backend} backend") + continue() + endif() + add_executable(boost_stacktrace_module_usage_${backend} ../../modules/samples/usage_sample.cpp) + target_link_libraries(boost_stacktrace_module_usage_${backend} PRIVATE Boost::stacktrace_${backend}) + target_compile_definitions(boost_stacktrace_module_usage_${backend} PRIVATE STACKTRACE_MODULE=boost.stacktrace.${backend}) + add_test(NAME boost_stacktrace_module_usage_${backend} COMMAND boost_stacktrace_module_usage_${backend}) + + add_executable(boost_stacktrace_from_exception_module_usage_${backend} ../../modules/samples/usage_sample_from_exception.cpp) + target_link_libraries(boost_stacktrace_from_exception_module_usage_${backend} PRIVATE Boost::stacktrace_${backend} Boost::stacktrace_from_exception) + target_compile_definitions(boost_stacktrace_from_exception_module_usage_${backend} PRIVATE STACKTRACE_MODULE=boost.stacktrace.${backend}) + add_test(NAME boost_stacktrace_from_exception_module_usage_${backend} COMMAND boost_stacktrace_from_exception_module_usage_${backend}) + endforeach() +endif() diff --git a/test/cmake_subdir_test/main.cpp b/test/cmake_subdir_test/main.cpp index 28a59714..3bb5024c 100644 --- a/test/cmake_subdir_test/main.cpp +++ b/test/cmake_subdir_test/main.cpp @@ -3,8 +3,8 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#include #include +#include int main() { diff --git a/test/test.cpp b/test/test.cpp index ff8c0a84..8333c0d1 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -4,9 +4,6 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include - -#include #include #include #include @@ -18,6 +15,8 @@ #include "test_impl.hpp" +#include + using boost::stacktrace::stacktrace; using boost::stacktrace::frame; diff --git a/test/test_from_exception.cpp b/test/test_from_exception.cpp index db5b36eb..47aad23f 100644 --- a/test/test_from_exception.cpp +++ b/test/test_from_exception.cpp @@ -4,13 +4,13 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include - #include #include #include +#include + namespace boost { namespace stacktrace { namespace impl { void assert_no_pending_traces() noexcept; }}} diff --git a/test/test_from_exception_none.cpp b/test/test_from_exception_none.cpp index a9762634..e3c4a4e5 100644 --- a/test/test_from_exception_none.cpp +++ b/test/test_from_exception_none.cpp @@ -4,10 +4,10 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include - #include +#include + using boost::stacktrace::stacktrace; diff --git a/test/test_torture.cpp b/test/test_torture.cpp index 2df475de..2008b2dc 100644 --- a/test/test_torture.cpp +++ b/test/test_torture.cpp @@ -11,8 +11,8 @@ // test and `top` does. -#include #include +#include #include "test_impl.hpp" diff --git a/test/test_trivial.cpp b/test/test_trivial.cpp index be21cc4b..98c6bd14 100644 --- a/test/test_trivial.cpp +++ b/test/test_trivial.cpp @@ -6,10 +6,10 @@ // See https://github.com/boostorg/stacktrace/issues/116 -#include - #include +#include + int main() { std::cout << boost::stacktrace::stacktrace() << std::endl; } diff --git a/test/test_void_ptr_cast.cpp b/test/test_void_ptr_cast.cpp index 5e569649..8d28d78e 100644 --- a/test/test_void_ptr_cast.cpp +++ b/test/test_void_ptr_cast.cpp @@ -4,10 +4,10 @@ // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) -#include - #include +#include + int foo1_func(int) { return 0; } void foo2_func(int, int, ...) {} From 28ea4a11387185cd57957328c879c55f2901af03 Mon Sep 17 00:00:00 2001 From: Fedor Osetrov Date: Sat, 9 May 2026 07:48:50 +0000 Subject: [PATCH 9/9] fix build --- CMakeLists.txt | 3 +++ modules/boost_stacktrace_addr2line.cppm | 9 --------- modules/boost_stacktrace_backtrace.cppm | 9 --------- modules/boost_stacktrace_basic.cppm | 9 --------- modules/boost_stacktrace_dump.cppm | 9 --------- modules/boost_stacktrace_noop.cppm | 8 -------- modules/samples/usage_sample_from_exception.cpp | 8 -------- 7 files changed, 3 insertions(+), 52 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87318c80..c753f23f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,6 +136,9 @@ else() endif() if(BOOST_USE_MODULES) + if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 20) + endif() if ((CMAKE_CXX_STANDARD IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD) AND CMAKE_CXX_MODULE_STD) message(STATUS "Using `import std;`") set(__import_std ON) diff --git a/modules/boost_stacktrace_addr2line.cppm b/modules/boost_stacktrace_addr2line.cppm index 310948d9..b8dee270 100644 --- a/modules/boost_stacktrace_addr2line.cppm +++ b/modules/boost_stacktrace_addr2line.cppm @@ -18,18 +18,12 @@ module; #include #include -<<<<<<< HEAD #if !defined(BOOST_STACKTRACE_USE_STD_MODULE) -======= ->>>>>>> develop #include #include #include #include -<<<<<<< HEAD #endif -======= ->>>>>>> develop #include #include @@ -42,13 +36,10 @@ module; export module boost.stacktrace.addr2line; -<<<<<<< HEAD #if defined(BOOST_STACKTRACE_USE_STD_MODULE) import std; #endif -======= ->>>>>>> develop import boost.stacktrace.dump; #ifdef __clang__ diff --git a/modules/boost_stacktrace_backtrace.cppm b/modules/boost_stacktrace_backtrace.cppm index 9f5c31b8..9860c200 100644 --- a/modules/boost_stacktrace_backtrace.cppm +++ b/modules/boost_stacktrace_backtrace.cppm @@ -20,18 +20,12 @@ module; #include -<<<<<<< HEAD #if !defined(BOOST_STACKTRACE_USE_STD_MODULE) -======= ->>>>>>> develop #include #include #include #include -<<<<<<< HEAD #endif -======= ->>>>>>> develop #include @@ -40,13 +34,10 @@ module; export module boost.stacktrace.backtrace; -<<<<<<< HEAD #if defined(BOOST_STACKTRACE_USE_STD_MODULE) import std; #endif -======= ->>>>>>> develop import boost.stacktrace.dump; #ifdef __clang__ diff --git a/modules/boost_stacktrace_basic.cppm b/modules/boost_stacktrace_basic.cppm index 98044c6b..15985c92 100644 --- a/modules/boost_stacktrace_basic.cppm +++ b/modules/boost_stacktrace_basic.cppm @@ -18,18 +18,12 @@ module; #include #include -<<<<<<< HEAD #if !defined(BOOST_STACKTRACE_USE_STD_MODULE) -======= ->>>>>>> develop #include #include #include #include -<<<<<<< HEAD #endif -======= ->>>>>>> develop #include @@ -38,13 +32,10 @@ module; export module boost.stacktrace.basic; -<<<<<<< HEAD #if defined(BOOST_STACKTRACE_USE_STD_MODULE) import std; #endif -======= ->>>>>>> develop import boost.stacktrace.dump; #ifdef __clang__ diff --git a/modules/boost_stacktrace_dump.cppm b/modules/boost_stacktrace_dump.cppm index 48cea357..b1fb6d8d 100644 --- a/modules/boost_stacktrace_dump.cppm +++ b/modules/boost_stacktrace_dump.cppm @@ -14,18 +14,12 @@ module; #include #include -<<<<<<< HEAD #if !defined(BOOST_STACKTRACE_USE_STD_MODULE) #include #endif #include #include -======= -#include -#include -#include ->>>>>>> develop #include #define BOOST_STACKTRACE_INTERFACE_UNIT @@ -33,13 +27,10 @@ module; export module boost.stacktrace.dump; -<<<<<<< HEAD #if defined(BOOST_STACKTRACE_USE_STD_MODULE) import std; #endif -======= ->>>>>>> develop #ifdef __clang__ # pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" #endif diff --git a/modules/boost_stacktrace_noop.cppm b/modules/boost_stacktrace_noop.cppm index cf4acfb8..789fe4bd 100644 --- a/modules/boost_stacktrace_noop.cppm +++ b/modules/boost_stacktrace_noop.cppm @@ -11,28 +11,20 @@ module; #include #include -<<<<<<< HEAD #if !defined(BOOST_STACKTRACE_USE_STD_MODULE) #include #include #endif -======= -#include -#include ->>>>>>> develop #define BOOST_STACKTRACE_INTERFACE_UNIT #define BOOST_STACKTRACE_LINK export module boost.stacktrace.noop; -<<<<<<< HEAD #if defined(BOOST_STACKTRACE_USE_STD_MODULE) import std; #endif -======= ->>>>>>> develop #ifdef __clang__ # pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" #endif diff --git a/modules/samples/usage_sample_from_exception.cpp b/modules/samples/usage_sample_from_exception.cpp index 5a11a078..832e8796 100644 --- a/modules/samples/usage_sample_from_exception.cpp +++ b/modules/samples/usage_sample_from_exception.cpp @@ -6,11 +6,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -<<<<<<< HEAD #include -======= -#include ->>>>>>> develop #include @@ -19,12 +15,8 @@ namespace { BOOST_NOINLINE void foo() { -<<<<<<< HEAD std::map m; std::ignore = m.at(1); -======= - throw std::logic_error{"Foo"}; ->>>>>>> develop } BOOST_NOINLINE void bar() {