Skip to content

Commit 8dd3018

Browse files
authored
feat stacktrace: independent dump library (#227)
This pull request introduces `boost_stacktrace_dump` library that is independent from backtrace implementations. The purpose is to make `boost_stacktrace_from_exception` also independent from specific backtrace implementation to further introduce C++20 modules support. As well, all stacktrace tests added to CMake CI. Header only library test also was added to CMake test.
1 parent d1e329d commit 8dd3018

25 files changed

Lines changed: 200 additions & 105 deletions

CMakeLists.txt

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
# Copyright 2020, 2021 Peter Dimov
2+
# Copyright 2026 Fedor Osetrov
23
# Distributed under the Boost Software License, Version 1.0.
34
# https://www.boost.org/LICENSE_1_0.txt
45

56
cmake_minimum_required(VERSION 3.8...4.20)
67

78
project(boost_stacktrace VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
89

9-
function(stacktrace_add_library suffix opt libs defs)
10+
function(stacktrace_add_library suffix opt public_libs libs defs)
1011

1112
if(NOT opt)
1213
return()
1314
endif()
1415

15-
add_library(boost_stacktrace_${suffix}
16-
src/${suffix}.cpp
17-
)
16+
add_library(boost_stacktrace_${suffix})
1817

1918
add_library(Boost::stacktrace_${suffix} ALIAS boost_stacktrace_${suffix})
2019

@@ -27,13 +26,21 @@ function(stacktrace_add_library suffix opt libs defs)
2726
Boost::core
2827
Boost::predef
2928
Boost::winapi
29+
${public_libs}
3030
PRIVATE
3131
${libs}
3232
)
3333

3434
target_compile_definitions(boost_stacktrace_${suffix}
35-
PUBLIC BOOST_STACKTRACE_NO_LIB
36-
PRIVATE BOOST_STACKTRACE_SOURCE ${defs}
35+
PUBLIC
36+
BOOST_STACKTRACE_NO_LIB
37+
PRIVATE
38+
${defs}
39+
)
40+
41+
target_sources(boost_stacktrace_${suffix}
42+
PRIVATE
43+
${CMAKE_CURRENT_LIST_DIR}/src/${suffix}.cpp
3744
)
3845

3946
if(BUILD_SHARED_LIBS)
@@ -50,26 +57,25 @@ endfunction()
5057

5158
include(CheckCXXSourceCompiles)
5259

53-
function(stacktrace_check var source incs libs defs)
60+
function(stacktrace_check var source incs libs)
5461

5562
set(CMAKE_REQUIRED_INCLUDES "${incs}")
5663
list(APPEND CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/build")
5764
set(CMAKE_REQUIRED_LIBRARIES "${libs}")
58-
set(CMAKE_REQUIRED_DEFINITIONS "${defs}")
5965
check_cxx_source_compiles("#include \"${source}\"" ${var})
6066
set(${var} ${${var}} PARENT_SCOPE)
6167

6268
endfunction()
6369

64-
stacktrace_check(BOOST_STACKTRACE_HAS_BACKTRACE has_backtrace.cpp "" "backtrace" "")
70+
stacktrace_check(BOOST_STACKTRACE_HAS_BACKTRACE has_backtrace.cpp "" "backtrace")
6571

6672
set(_default_addr2line ON)
6773
if(WIN32 AND NOT CMAKE_CXX_PLATFORM_ID MATCHES "Cygwin")
6874
set(_default_addr2line OFF)
6975
endif()
7076

71-
stacktrace_check(BOOST_STACKTRACE_HAS_WINDBG has_windbg.cpp "" "dbgeng;ole32" "")
72-
stacktrace_check(BOOST_STACKTRACE_HAS_WINDBG_CACHED has_windbg_cached.cpp "${CMAKE_CURRENT_SOURCE_DIR}/../config/include" "dbgeng;ole32" "")
77+
stacktrace_check(BOOST_STACKTRACE_HAS_WINDBG has_windbg.cpp "" "dbgeng;ole32")
78+
stacktrace_check(BOOST_STACKTRACE_HAS_WINDBG_CACHED has_windbg_cached.cpp "${CMAKE_CURRENT_SOURCE_DIR}/../config/include" "dbgeng;ole32")
7379

7480
set(_default_from_exception ON)
7581
if (CMAKE_CXX_PLATFORM_ID MATCHES "Cygwin")
@@ -97,51 +103,59 @@ message(STATUS "Boost.Stacktrace: "
97103
"from_exception ${BOOST_STACKTRACE_ENABLE_FROM_EXCEPTION}"
98104
)
99105

100-
stacktrace_add_library(noop ${BOOST_STACKTRACE_ENABLE_NOOP} "" "")
101-
stacktrace_add_library(backtrace ${BOOST_STACKTRACE_ENABLE_BACKTRACE} "backtrace;${CMAKE_DL_LIBS}" "")
102-
stacktrace_add_library(addr2line ${BOOST_STACKTRACE_ENABLE_ADDR2LINE} "${CMAKE_DL_LIBS}" "")
103-
stacktrace_add_library(basic ${BOOST_STACKTRACE_ENABLE_BASIC} "${CMAKE_DL_LIBS}" "")
104-
stacktrace_add_library(windbg ${BOOST_STACKTRACE_ENABLE_WINDBG} "dbgeng;ole32" "_GNU_SOURCE=1")
105-
stacktrace_add_library(windbg_cached ${BOOST_STACKTRACE_ENABLE_WINDBG_CACHED} "dbgeng;ole32" "_GNU_SOURCE=1")
106+
if(BOOST_STACKTRACE_ENABLE_BACKTRACE OR
107+
BOOST_STACKTRACE_ENABLE_ADDR2LINE OR
108+
BOOST_STACKTRACE_ENABLE_BASIC OR
109+
BOOST_STACKTRACE_ENABLE_WINDBG OR
110+
BOOST_STACKTRACE_ENABLE_WINDBG_CACHED
111+
)
112+
set(_enable_non_noop_backend TRUE)
113+
endif()
114+
115+
if(_enable_non_noop_backend)
116+
stacktrace_add_library(dump ON "" "" "")
117+
endif()
118+
stacktrace_add_library(noop ${BOOST_STACKTRACE_ENABLE_NOOP} "" "" "")
119+
stacktrace_add_library(backtrace ${BOOST_STACKTRACE_ENABLE_BACKTRACE} Boost::stacktrace_dump "backtrace;${CMAKE_DL_LIBS}" "")
120+
stacktrace_add_library(addr2line ${BOOST_STACKTRACE_ENABLE_ADDR2LINE} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "")
121+
stacktrace_add_library(basic ${BOOST_STACKTRACE_ENABLE_BASIC} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "")
122+
stacktrace_add_library(windbg ${BOOST_STACKTRACE_ENABLE_WINDBG} Boost::stacktrace_dump "dbgeng;ole32" "_GNU_SOURCE=1")
123+
stacktrace_add_library(windbg_cached ${BOOST_STACKTRACE_ENABLE_WINDBG_CACHED} Boost::stacktrace_dump "dbgeng;ole32" "_GNU_SOURCE=1")
106124

107125
# boost_stacktrace, default library
108126

109127
add_library(boost_stacktrace INTERFACE)
110-
add_library(Boost::stacktrace ALIAS boost_stacktrace)
111128

112129
target_include_directories(boost_stacktrace INTERFACE include)
113130

114-
if(BOOST_STACKTRACE_ENABLE_WINDBG)
115-
116-
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_windbg)
131+
add_library(Boost::stacktrace ALIAS boost_stacktrace)
117132

133+
if(BOOST_STACKTRACE_ENABLE_WINDBG)
134+
set(__default_stacktrace_backend "windbg")
118135
elseif(BOOST_STACKTRACE_ENABLE_WINDBG_CACHED)
119-
120-
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_windbg)
121-
136+
set(__default_stacktrace_backend "windbg_cached")
122137
elseif(BOOST_STACKTRACE_ENABLE_BACKTRACE)
123-
124-
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_backtrace)
125-
138+
set(__default_stacktrace_backend "backtrace")
126139
elseif(BOOST_STACKTRACE_ENABLE_ADDR2LINE)
127-
128-
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_addr2line)
129-
140+
set(__default_stacktrace_backend "addr2line")
130141
elseif(BOOST_STACKTRACE_ENABLE_BASIC)
131-
132-
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_basic)
133-
142+
set(__default_stacktrace_backend "basic")
134143
elseif(BOOST_STACKTRACE_ENABLE_NOOP)
135-
136-
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_noop)
137-
144+
set(__default_stacktrace_backend "noop")
145+
else()
146+
message(FATAL "All backends are disabled")
138147
endif()
139148

140-
# Boost::stacktrace_from_exception is never the default
141-
stacktrace_add_library(from_exception ${BOOST_STACKTRACE_ENABLE_FROM_EXCEPTION} "${CMAKE_DL_LIBS};boost_stacktrace" "")
149+
message(STATUS "Boost.stacktrace default backend: ${__default_stacktrace_backend}")
150+
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_${__default_stacktrace_backend})
142151

143-
#
152+
# Boost::stacktrace_from_exception is never the default
153+
if(_enable_non_noop_backend)
154+
stacktrace_add_library(from_exception ${BOOST_STACKTRACE_ENABLE_FROM_EXCEPTION} Boost::stacktrace_dump "${CMAKE_DL_LIBS}" "")
155+
unset(_enable_non_noop_backend)
156+
endif()
144157

145158
if(BUILD_TESTING)
146159
add_subdirectory(test)
147160
endif()
161+
unset(__default_stacktrace_backend)

build.jam

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,17 @@ project /boost/stacktrace
2020
;
2121

2222
explicit
23-
[ alias boost_stacktrace_addr2line : build//boost_stacktrace_addr2line ]
23+
[ alias boost_stacktrace_dump : build//boost_stacktrace_dump ]
2424
[ alias boost_stacktrace_backtrace : build//boost_stacktrace_backtrace ]
25+
[ alias boost_stacktrace_addr2line : build//boost_stacktrace_addr2line ]
2526
[ alias boost_stacktrace_basic : build//boost_stacktrace_basic ]
2627
[ alias boost_stacktrace_from_exception : build//boost_stacktrace_from_exception ]
2728
[ alias boost_stacktrace_noop : build//boost_stacktrace_noop ]
2829
[ alias boost_stacktrace_windbg : build//boost_stacktrace_windbg ]
2930
[ alias boost_stacktrace_windbg_cached : build//boost_stacktrace_windbg_cached ]
3031
[ alias boost_stacktrace : boost_stacktrace_noop ]
3132
[ alias all :
33+
boost_stacktrace_dump
3234
boost_stacktrace_addr2line
3335
boost_stacktrace_backtrace
3436
boost_stacktrace_basic
@@ -42,6 +44,7 @@ explicit
4244

4345
call-if : boost-library stacktrace
4446
: install
47+
boost_stacktrace_dump
4548
boost_stacktrace_addr2line
4649
boost_stacktrace_backtrace
4750
boost_stacktrace_basic

build/Jamfile.v2

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ explicit WinDbg ;
6565
mp-run-simple has_windbg_cached.cpp : : : <library>Dbgeng <library>ole32 : WinDbgCached ;
6666
explicit WinDbgCached ;
6767

68+
lib boost_stacktrace_dump
69+
: # sources
70+
../src/dump.cpp
71+
: # requirements
72+
<warnings>all
73+
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
74+
: # default build
75+
: # usage-requirements
76+
<define>BOOST_STACKTRACE_NO_LIB=1
77+
;
78+
6879
rule build-stacktrace-noop ( props * )
6980
{
7081
local enabled = [ property.select <boost.stacktrace.noop> : $(props) ] ;
@@ -109,13 +120,15 @@ lib boost_stacktrace_backtrace
109120
: # requirements
110121
<warnings>all
111122
<target-os>linux:<library>dl
123+
<library>boost_stacktrace_dump
112124
<library>backtrace
113125
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
114126
<conditional>@build-stacktrace-backtrace
115127
: # default build
116128
: # usage-requirements
117129
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
118130
<define>BOOST_STACKTRACE_NO_LIB=1
131+
<library>boost_stacktrace_dump
119132
;
120133

121134
rule build-stacktrace-addr2line ( props * )
@@ -146,12 +159,14 @@ lib boost_stacktrace_addr2line
146159
: # requirements
147160
<warnings>all
148161
<target-os>linux:<library>dl
162+
<library>boost_stacktrace_dump
149163
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
150164
<conditional>@build-stacktrace-addr2line
151165
: # default build
152166
: # usage-requirements
153167
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
154168
<define>BOOST_STACKTRACE_NO_LIB=1
169+
<library>boost_stacktrace_dump
155170
;
156171

157172
rule build-stacktrace-basic ( props * )
@@ -175,12 +190,14 @@ lib boost_stacktrace_basic
175190
: # requirements
176191
<warnings>all
177192
<target-os>linux:<library>dl
193+
<library>boost_stacktrace_dump
178194
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
179195
<conditional>@build-stacktrace-basic
180196
: # default build
181197
: # usage-requirements
182198
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
183199
<define>BOOST_STACKTRACE_NO_LIB=1
200+
<library>boost_stacktrace_dump
184201
;
185202

186203
rule build-stacktrace-windbg ( props * )
@@ -203,13 +220,15 @@ lib boost_stacktrace_windbg
203220
../src/windbg.cpp
204221
: # requirements
205222
<warnings>all
223+
<library>boost_stacktrace_dump
206224
<library>Dbgeng <library>ole32
207225
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
208226
<conditional>@build-stacktrace-windbg
209227
: # default build
210228
: # usage-requirements
211229
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
212230
<define>BOOST_STACKTRACE_NO_LIB=1
231+
<library>boost_stacktrace_dump
213232
;
214233

215234
rule build-stacktrace-windbg-cached ( props * )
@@ -232,13 +251,15 @@ lib boost_stacktrace_windbg_cached
232251
../src/windbg_cached.cpp
233252
: # requirements
234253
<warnings>all
254+
<library>boost_stacktrace_dump
235255
<library>Dbgeng <library>ole32
236256
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
237257
<conditional>@build-stacktrace-windbg-cached
238258
: # default build
239259
: # usage-requirements
240260
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
241261
<define>BOOST_STACKTRACE_NO_LIB=1
262+
<library>boost_stacktrace_dump
242263
;
243264

244265
rule build-stacktrace-from-exception ( props * )
@@ -264,6 +285,7 @@ lib boost_stacktrace_from_exception
264285
: # requirements
265286
<warnings>all
266287
<target-os>linux:<library>dl
288+
<library>boost_stacktrace_dump
267289
<target-os>windows:<library>ucrt
268290

269291
# Enable build when explicitly requested, or by default, when on x86
@@ -272,4 +294,5 @@ lib boost_stacktrace_from_exception
272294
: # usage-requirements
273295
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
274296
<define>BOOST_STACKTRACE_NO_LIB=1
297+
<library>boost_stacktrace_dump
275298
;

include/boost/stacktrace/detail/frame_decl.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# pragma once
1313
#endif
1414

15-
#include <iosfwd>
1615
#include <string>
1716

1817
#include <boost/stacktrace/safe_dump_to.hpp> // boost::stacktrace::detail::native_frame_ptr_t

include/boost/stacktrace/frame.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
#include <iosfwd>
1616
#include <string>
1717

18-
#include <boost/stacktrace/safe_dump_to.hpp> // boost::stacktrace::detail::native_frame_ptr_t
19-
2018
#include <boost/stacktrace/detail/frame_decl.hpp>
2119
#include <boost/stacktrace/detail/push_options.h>
2220

@@ -64,7 +62,7 @@ std::basic_ostream<CharT, TraitsT>& operator<<(std::basic_ostream<CharT, TraitsT
6462

6563
#include <boost/stacktrace/detail/pop_options.h>
6664

67-
#ifndef BOOST_STACKTRACE_LINK
65+
#if !defined(BOOST_STACKTRACE_LINK)
6866
# if defined(BOOST_STACKTRACE_USE_NOOP)
6967
# include <boost/stacktrace/detail/frame_noop.ipp>
7068
# elif defined(BOOST_MSVC) || defined(BOOST_STACKTRACE_USE_WINDBG) || defined(BOOST_STACKTRACE_USE_WINDBG_CACHED)

include/boost/stacktrace/safe_dump_to.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_dep
205205

206206
#include <boost/stacktrace/detail/pop_options.h>
207207

208-
#if !defined(BOOST_STACKTRACE_LINK) || defined(BOOST_STACKTRACE_INTERNAL_BUILD_LIBS)
208+
#if !defined(BOOST_STACKTRACE_LINK)
209209
# if defined(BOOST_STACKTRACE_USE_NOOP)
210210
# include <boost/stacktrace/detail/safe_dump_noop.ipp>
211211
# include <boost/stacktrace/detail/collect_noop.ipp>

src/addr2line.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
#endif
1414

1515
#include <boost/stacktrace/detail/frame_unwind.ipp>
16-
#include <boost/stacktrace/safe_dump_to.hpp>
16+

src/backtrace.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
#endif
1414

1515
#include <boost/stacktrace/detail/frame_unwind.ipp>
16-
#include <boost/stacktrace/safe_dump_to.hpp>
16+

src/basic.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,3 @@
1212
#endif
1313

1414
#include <boost/stacktrace/detail/frame_unwind.ipp>
15-
#include <boost/stacktrace/safe_dump_to.hpp>

src/dump.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright Antony Polukhin, 2025-2026
2+
// Copyright Fedor Osetrov, 2025-2026
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See
5+
// accompanying file LICENSE_1_0.txt or copy at
6+
// http://www.boost.org/LICENSE_1_0.txt)
7+
8+
#define BOOST_STACKTRACE_LINK
9+
#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
10+
11+
#ifndef _GNU_SOURCE
12+
# define _GNU_SOURCE
13+
#endif
14+
15+
#include <boost/config.hpp>
16+
17+
#if defined(BOOST_WINDOWS)
18+
# include <boost/stacktrace/detail/safe_dump_win.ipp>
19+
#else
20+
# include <boost/stacktrace/detail/safe_dump_posix.ipp>
21+
#endif
22+
#if defined(BOOST_WINDOWS) && !defined(BOOST_WINAPI_IS_MINGW) // MinGW does not provide RtlCaptureStackBackTrace. MinGW-w64 does.
23+
# include <boost/stacktrace/detail/collect_msvc.ipp>
24+
#else
25+
# include <boost/stacktrace/detail/collect_unwind.ipp>
26+
#endif

0 commit comments

Comments
 (0)