mirror of
https://github.com/boostorg/stacktrace.git
synced 2026-01-28 19:52:08 +00:00
Compare commits
64 Commits
boost-1.85
...
boost-1.88
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6499f26d4 | ||
|
|
d408cf4468 | ||
|
|
9d314b2b47 | ||
|
|
54934a386a | ||
|
|
ea282324b8 | ||
|
|
9e7a98a61a | ||
|
|
b170b28479 | ||
|
|
5ec45912da | ||
|
|
679bd845aa | ||
|
|
0bcc382ab5 | ||
|
|
a64b8b7985 | ||
|
|
92b1c794b3 | ||
|
|
8c4e50324c | ||
|
|
22982db3f6 | ||
|
|
088bf8ed7f | ||
|
|
344f6bae19 | ||
|
|
6504ed9ea4 | ||
|
|
a778e3d223 | ||
|
|
464e224c2f | ||
|
|
3f79aee92f | ||
|
|
da94896d2d | ||
|
|
0a1f8ac9a0 | ||
|
|
7c79d84614 | ||
|
|
e95c2723d8 | ||
|
|
9028c8a413 | ||
|
|
b37fc77b5d | ||
|
|
aa97b1a34c | ||
|
|
23e1213f54 | ||
|
|
ad121dbed0 | ||
|
|
981e37c218 | ||
|
|
cbf0df774d | ||
|
|
34e56c4e90 | ||
|
|
f32bd5a543 | ||
|
|
79fc075655 | ||
|
|
6624a0aaeb | ||
|
|
ca76415503 | ||
|
|
4352901d19 | ||
|
|
2820ed36b5 | ||
|
|
1a389747a3 | ||
|
|
1db160d566 | ||
|
|
1b16c5d6ae | ||
|
|
274aeaa351 | ||
|
|
a615135de0 | ||
|
|
32749a7041 | ||
|
|
08d4f46333 | ||
|
|
97bc049bcb | ||
|
|
98ed11d235 | ||
|
|
f1c5cd8963 | ||
|
|
94f11c52eb | ||
|
|
f6f3623594 | ||
|
|
aad95c2667 | ||
|
|
a95e7e5860 | ||
|
|
8b79199a2a | ||
|
|
6e39a41abf | ||
|
|
5747f85c0b | ||
|
|
c093aef138 | ||
|
|
66c0f7a54f | ||
|
|
aacfc2e557 | ||
|
|
80af3a44c3 | ||
|
|
69260779d1 | ||
|
|
2c83563695 | ||
|
|
39afcefb64 | ||
|
|
d1b7a61353 | ||
|
|
351b03d522 |
339
.github/workflows/ci.yml
vendored
339
.github/workflows/ci.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
@@ -126,7 +126,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
@@ -165,3 +165,338 @@ jobs:
|
||||
with:
|
||||
github-token: ${{ secrets.github_token }}
|
||||
parallel-finished: true
|
||||
|
||||
posix-cmake-subdir:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-20.04, ubuntu-22.04, macos-13, macos-14 ]
|
||||
shared: [ OFF, ON ]
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt-get -y install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- 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
|
||||
|
||||
posix-cmake-install:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-20.04, ubuntu-22.04, macos-13, macos-14 ]
|
||||
shared: [ OFF, ON ]
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt-get -y install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cd ../boost-root
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local -DBUILD_SHARED_LIBS=${{matrix.shared}} ..
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build .
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target install
|
||||
|
||||
- name: Use the installed library
|
||||
run: |
|
||||
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
|
||||
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
cmake --build .
|
||||
export LD_LIBRARY_PATH=$HOME/.local/lib:$LD_LIBRARY_PATH
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
posix-cmake-test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-20.04, ubuntu-22.04, macos-13, macos-14 ]
|
||||
shared: [ OFF, ON ]
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt-get -y install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Configure (Debug)
|
||||
run: |
|
||||
cd ../boost-root
|
||||
mkdir __build_debug__ && cd __build_debug__
|
||||
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON -DBUILD_SHARED_LIBS=${{matrix.shared}} -DCMAKE_BUILD_TYPE=Debug ..
|
||||
|
||||
- name: Build tests (Debug)
|
||||
run: |
|
||||
cd ../boost-root/__build_debug__
|
||||
cmake --build . --target tests
|
||||
|
||||
- name: Run tests (Debug)
|
||||
run: |
|
||||
cd ../boost-root/__build_debug__
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
windows-cmake-subdir:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ windows-2019, windows-2022 ]
|
||||
shared: [ OFF, ON ]
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
|
||||
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
|
||||
echo LIBRARY: %LIBRARY%
|
||||
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
|
||||
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
|
||||
echo GITHUB_REF: %GITHUB_REF%
|
||||
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
|
||||
set BOOST_BRANCH=develop
|
||||
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
|
||||
echo BOOST_BRANCH: %BOOST_BRANCH%
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
|
||||
|
||||
- name: Use library with add_subdirectory (Debug)
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBUILD_SHARED_LIBS=${{matrix.shared}} ..
|
||||
cmake --build . --config Debug
|
||||
ctest --output-on-failure --no-tests=error -C Debug
|
||||
|
||||
- name: Use library with add_subdirectory (RelWithDebInfo)
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test/__build__
|
||||
cmake --build . --config RelWithDebInfo
|
||||
ctest --output-on-failure --no-tests=error -C RelWithDebInfo
|
||||
|
||||
windows-cmake-install:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ windows-2019, windows-2022 ]
|
||||
shared: [ OFF, ON ]
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
|
||||
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
|
||||
echo LIBRARY: %LIBRARY%
|
||||
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
|
||||
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
|
||||
echo GITHUB_REF: %GITHUB_REF%
|
||||
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
|
||||
set BOOST_BRANCH=develop
|
||||
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
|
||||
echo BOOST_BRANCH: %BOOST_BRANCH%
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
|
||||
|
||||
- name: Configure
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix -DBUILD_SHARED_LIBS=${{matrix.shared}} ..
|
||||
|
||||
- name: Install (Debug)
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target install --config Debug
|
||||
|
||||
- name: Install (RelWithDebInfo)
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target install --config RelWithDebInfo
|
||||
|
||||
- name: Use the installed library (Debug)
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test && mkdir __build__ && cd __build__
|
||||
cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
|
||||
cmake --build . --config Debug
|
||||
PATH C:\cmake-prefix\bin;%PATH%
|
||||
ctest --output-on-failure --no-tests=error -C Debug
|
||||
|
||||
- name: Use the installed library (RelWithDebInfo)
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test/__build__
|
||||
cmake --build . --config RelWithDebInfo
|
||||
PATH C:\cmake-prefix\bin;%PATH%
|
||||
ctest --output-on-failure --no-tests=error -C RelWithDebInfo
|
||||
|
||||
windows-cmake-test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ windows-2019, windows-2022 ]
|
||||
shared: [ OFF, ON ]
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
|
||||
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
|
||||
echo LIBRARY: %LIBRARY%
|
||||
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
|
||||
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
|
||||
echo GITHUB_REF: %GITHUB_REF%
|
||||
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
|
||||
set BOOST_BRANCH=develop
|
||||
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
|
||||
echo BOOST_BRANCH: %BOOST_BRANCH%
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
|
||||
|
||||
- name: Configure
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DBUILD_TESTING=ON -DBUILD_SHARED_LIBS=${{matrix.shared}} ..
|
||||
|
||||
- name: Build tests (Debug)
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target tests --config Debug
|
||||
|
||||
- name: Run tests (Debug)
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
ctest --output-on-failure --no-tests=error -C Debug
|
||||
|
||||
- name: Build tests (RelWithDebInfo)
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target tests --config RelWithDebInfo
|
||||
|
||||
- name: Run tests (RelWithDebInfo)
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
ctest --output-on-failure --no-tests=error -C RelWithDebInfo
|
||||
|
||||
@@ -71,14 +71,21 @@ endif()
|
||||
stacktrace_check(BOOST_STACKTRACE_HAS_WINDBG has_windbg.cpp "" "dbgeng;ole32" "")
|
||||
stacktrace_check(BOOST_STACKTRACE_HAS_WINDBG_CACHED has_windbg_cached.cpp "${CMAKE_CURRENT_SOURCE_DIR}/../config/include" "dbgeng;ole32" "")
|
||||
|
||||
set(_default_from_exception ON)
|
||||
if (NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64|i386|i686|x86")
|
||||
set(_default_from_exception OFF)
|
||||
endif()
|
||||
|
||||
option(BOOST_STACKTRACE_ENABLE_NOOP "Boost.Stacktrace: build boost_stacktrace_noop" ON)
|
||||
option(BOOST_STACKTRACE_ENABLE_BACKTRACE "Boost.Stacktrace: build boost_stacktrace_backtrace" ${BOOST_STACKTRACE_HAS_BACKTRACE})
|
||||
option(BOOST_STACKTRACE_ENABLE_ADDR2LINE "Boost.Stacktrace: build boost_stacktrace_addr2line" ${_default_addr2line})
|
||||
option(BOOST_STACKTRACE_ENABLE_BASIC "Boost.Stacktrace: build boost_stacktrace_basic" ON)
|
||||
option(BOOST_STACKTRACE_ENABLE_WINDBG "Boost.Stacktrace: build boost_stacktrace_windbg" ${BOOST_STACKTRACE_HAS_WINDBG})
|
||||
option(BOOST_STACKTRACE_ENABLE_WINDBG_CACHED "Boost.Stacktrace: build boost_stacktrace_windbg_cached" ${BOOST_STACKTRACE_HAS_WINDBG_CACHED})
|
||||
option(BOOST_STACKTRACE_ENABLE_FROM_EXCEPTION "Boost.Stacktrace: build boost_stacktrace_from_exception" ${_default_from_exception})
|
||||
|
||||
unset(_default_addr2line)
|
||||
unset(_default_from_exception)
|
||||
|
||||
message(STATUS "Boost.Stacktrace: "
|
||||
"noop ${BOOST_STACKTRACE_ENABLE_NOOP}, "
|
||||
@@ -86,16 +93,55 @@ message(STATUS "Boost.Stacktrace: "
|
||||
"addr2line ${BOOST_STACKTRACE_ENABLE_ADDR2LINE}, "
|
||||
"basic ${BOOST_STACKTRACE_ENABLE_BASIC}, "
|
||||
"windbg ${BOOST_STACKTRACE_ENABLE_WINDBG}, "
|
||||
"windbg_cached ${BOOST_STACKTRACE_ENABLE_WINDBG_CACHED}"
|
||||
"windbg_cached ${BOOST_STACKTRACE_ENABLE_WINDBG_CACHED}, "
|
||||
"from_exception ${BOOST_STACKTRACE_ENABLE_FROM_EXCEPTION}"
|
||||
)
|
||||
|
||||
stacktrace_add_library(noop ${BOOST_STACKTRACE_ENABLE_NOOP} "" "")
|
||||
stacktrace_add_library(backtrace ${BOOST_STACKTRACE_ENABLE_BACKTRACE} "backtrace" "")
|
||||
stacktrace_add_library(addr2line ${BOOST_STACKTRACE_ENABLE_ADDR2LINE} "" "")
|
||||
stacktrace_add_library(basic ${BOOST_STACKTRACE_ENABLE_BASIC} "" "")
|
||||
stacktrace_add_library(backtrace ${BOOST_STACKTRACE_ENABLE_BACKTRACE} "backtrace;${CMAKE_DL_LIBS}" "")
|
||||
stacktrace_add_library(addr2line ${BOOST_STACKTRACE_ENABLE_ADDR2LINE} "${CMAKE_DL_LIBS}" "")
|
||||
stacktrace_add_library(basic ${BOOST_STACKTRACE_ENABLE_BASIC} "${CMAKE_DL_LIBS}" "")
|
||||
stacktrace_add_library(windbg ${BOOST_STACKTRACE_ENABLE_WINDBG} "dbgeng;ole32" "_GNU_SOURCE=1")
|
||||
stacktrace_add_library(windbg_cached ${BOOST_STACKTRACE_ENABLE_WINDBG_CACHED} "dbgeng;ole32" "_GNU_SOURCE=1")
|
||||
|
||||
# boost_stacktrace, default library
|
||||
|
||||
add_library(boost_stacktrace INTERFACE)
|
||||
add_library(Boost::stacktrace ALIAS boost_stacktrace)
|
||||
|
||||
target_include_directories(boost_stacktrace INTERFACE include)
|
||||
|
||||
if(BOOST_STACKTRACE_ENABLE_WINDBG)
|
||||
|
||||
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_windbg)
|
||||
|
||||
elseif(BOOST_STACKTRACE_ENABLE_WINDBG_CACHED)
|
||||
|
||||
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_windbg)
|
||||
|
||||
elseif(BOOST_STACKTRACE_ENABLE_BACKTRACE)
|
||||
|
||||
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_backtrace)
|
||||
|
||||
elseif(BOOST_STACKTRACE_ENABLE_ADDR2LINE)
|
||||
|
||||
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_addr2line)
|
||||
|
||||
elseif(BOOST_STACKTRACE_ENABLE_BASIC)
|
||||
|
||||
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_basic)
|
||||
|
||||
elseif(BOOST_STACKTRACE_ENABLE_NOOP)
|
||||
|
||||
target_link_libraries(boost_stacktrace INTERFACE Boost::stacktrace_noop)
|
||||
|
||||
endif()
|
||||
|
||||
# Boost::stacktrace_from_exception is never the default
|
||||
stacktrace_add_library(from_exception ${BOOST_STACKTRACE_ENABLE_FROM_EXCEPTION} "${CMAKE_DL_LIBS};boost_stacktrace" "")
|
||||
|
||||
#
|
||||
|
||||
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
15
boost-stacktrace-features.jam
Normal file
15
boost-stacktrace-features.jam
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2016-2024, Antony Polukhin.
|
||||
#
|
||||
# Use, modification and distribution is subject to 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)
|
||||
#
|
||||
import feature ;
|
||||
|
||||
feature.feature boost.stacktrace.noop : on off : optional propagated ;
|
||||
feature.feature boost.stacktrace.backtrace : on off : optional propagated ;
|
||||
feature.feature boost.stacktrace.addr2line : on off : optional propagated ;
|
||||
feature.feature boost.stacktrace.basic : on off : optional propagated ;
|
||||
feature.feature boost.stacktrace.windbg : on off : optional propagated ;
|
||||
feature.feature boost.stacktrace.windbg_cached : on off : optional propagated ;
|
||||
feature.feature boost.stacktrace.from_exception : on off : optional propagated ;
|
||||
52
build.jam
Normal file
52
build.jam
Normal file
@@ -0,0 +1,52 @@
|
||||
# Copyright René Ferdinand Rivera Morell 2023-2024
|
||||
# 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)
|
||||
|
||||
require-b2 5.2 ;
|
||||
|
||||
import boost-stacktrace-features ;
|
||||
|
||||
constant boost_dependencies :
|
||||
<library>/boost/config//boost_config
|
||||
<library>/boost/container_hash//boost_container_hash
|
||||
<library>/boost/core//boost_core
|
||||
<library>/boost/predef//boost_predef
|
||||
<target-os>windows:<library>/boost/winapi//boost_winapi ;
|
||||
|
||||
project /boost/stacktrace
|
||||
: common-requirements
|
||||
<include>include
|
||||
;
|
||||
|
||||
explicit
|
||||
[ alias boost_stacktrace_addr2line : build//boost_stacktrace_addr2line ]
|
||||
[ alias boost_stacktrace_backtrace : build//boost_stacktrace_backtrace ]
|
||||
[ alias boost_stacktrace_basic : build//boost_stacktrace_basic ]
|
||||
[ alias boost_stacktrace_from_exception : build//boost_stacktrace_from_exception ]
|
||||
[ alias boost_stacktrace_noop : build//boost_stacktrace_noop ]
|
||||
[ alias boost_stacktrace_windbg : build//boost_stacktrace_windbg ]
|
||||
[ alias boost_stacktrace_windbg_cached : build//boost_stacktrace_windbg_cached ]
|
||||
[ alias boost_stacktrace : boost_stacktrace_noop ]
|
||||
[ alias all :
|
||||
boost_stacktrace_addr2line
|
||||
boost_stacktrace_backtrace
|
||||
boost_stacktrace_basic
|
||||
boost_stacktrace_from_exception
|
||||
boost_stacktrace_noop
|
||||
boost_stacktrace_windbg
|
||||
boost_stacktrace_windbg_cached
|
||||
test
|
||||
]
|
||||
;
|
||||
|
||||
call-if : boost-library stacktrace
|
||||
: install
|
||||
boost_stacktrace_addr2line
|
||||
boost_stacktrace_backtrace
|
||||
boost_stacktrace_basic
|
||||
boost_stacktrace_from_exception
|
||||
boost_stacktrace_noop
|
||||
boost_stacktrace_windbg
|
||||
boost_stacktrace_windbg_cached
|
||||
;
|
||||
159
build/Jamfile.v2
159
build/Jamfile.v2
@@ -5,13 +5,22 @@
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
|
||||
import feature ;
|
||||
import ../../config/checks/config : requires ;
|
||||
require-b2 5.0.1 ;
|
||||
import-search /boost/config/checks ;
|
||||
import boost-stacktrace-features ;
|
||||
import config : requires ;
|
||||
import configure ;
|
||||
import property ;
|
||||
|
||||
constant boost_dependencies_private :
|
||||
<library>/boost/assert//boost_assert
|
||||
;
|
||||
|
||||
project
|
||||
: source-location .
|
||||
: common-requirements $(boost_dependencies)
|
||||
: requirements
|
||||
[ requires cxx11_rvalue_references ]
|
||||
$(boost_dependencies_private)
|
||||
: default-build
|
||||
<visibility>hidden
|
||||
;
|
||||
@@ -21,14 +30,12 @@ lib gcc_s ;
|
||||
lib Dbgeng ;
|
||||
lib ole32 ;
|
||||
|
||||
feature.feature boost.stacktrace.from_exception : on off : optional propagated ;
|
||||
|
||||
local LIBBACKTRACE_PATH = [ modules.peek : LIBBACKTRACE_PATH ] ;
|
||||
lib backtrace
|
||||
:
|
||||
:
|
||||
: <search>$(LIBBACKTRACE_PATH)/lib <link>static
|
||||
:
|
||||
: <include>$(LIBBACKTRACE_PATH)/include
|
||||
: <include>$(LIBBACKTRACE_PATH)/include
|
||||
;
|
||||
|
||||
actions mp_simple_run_action
|
||||
@@ -57,17 +64,44 @@ explicit WinDbg ;
|
||||
mp-run-simple has_windbg_cached.cpp : : : <library>Dbgeng <library>ole32 : WinDbgCached ;
|
||||
explicit WinDbgCached ;
|
||||
|
||||
rule build-stacktrace-noop ( props * )
|
||||
{
|
||||
local enabled = [ property.select <boost.stacktrace.noop> : $(props) ] ;
|
||||
switch $(enabled:G=)
|
||||
{
|
||||
case "on" : return ;
|
||||
case "off" : return <build>no ;
|
||||
}
|
||||
}
|
||||
|
||||
lib boost_stacktrace_noop
|
||||
: # sources
|
||||
../src/noop.cpp
|
||||
: # requirements
|
||||
<warnings>all
|
||||
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
<conditional>@build-stacktrace-noop
|
||||
: # default build
|
||||
: # usage-requirements
|
||||
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
<define>BOOST_STACKTRACE_NO_LIB=1
|
||||
;
|
||||
|
||||
rule build-stacktrace-backtrace ( props * )
|
||||
{
|
||||
local enabled = [ property.select <boost.stacktrace.backtrace> : $(props) ] ;
|
||||
switch $(enabled:G=)
|
||||
{
|
||||
case "on" : return ;
|
||||
case "off" : return <build>no ;
|
||||
}
|
||||
|
||||
if ! [ configure.builds libbacktrace : $(props) : "boost.stacktrace.backtrace" ]
|
||||
{
|
||||
return <build>no ;
|
||||
}
|
||||
}
|
||||
|
||||
lib boost_stacktrace_backtrace
|
||||
: # sources
|
||||
../src/backtrace.cpp
|
||||
@@ -76,12 +110,35 @@ lib boost_stacktrace_backtrace
|
||||
<target-os>linux:<library>dl
|
||||
<library>backtrace
|
||||
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
[ check-target-builds ../build//libbacktrace : : <build>no ]
|
||||
<conditional>@build-stacktrace-backtrace
|
||||
: # default build
|
||||
: # usage-requirements
|
||||
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
<define>BOOST_STACKTRACE_NO_LIB=1
|
||||
;
|
||||
|
||||
rule build-stacktrace-addr2line ( props * )
|
||||
{
|
||||
local enabled = [ property.select <boost.stacktrace.addr2line> : $(props) ] ;
|
||||
switch $(enabled:G=)
|
||||
{
|
||||
case "on" : return ;
|
||||
case "off" : return <build>no ;
|
||||
}
|
||||
|
||||
# Disable by default on Windows when not using Cygwin
|
||||
if <target-os>windows in $(props) && ! ( <target-os>cygwin in $(props) )
|
||||
{
|
||||
configure.log-library-search-result "boost.stacktrace.addr2line" : "no" ;
|
||||
return <build>no ;
|
||||
}
|
||||
|
||||
if ! [ configure.builds addr2line : $(props) : "boost.stacktrace.addr2line" ]
|
||||
{
|
||||
return <build>no ;
|
||||
}
|
||||
}
|
||||
|
||||
lib boost_stacktrace_addr2line
|
||||
: # sources
|
||||
../src/addr2line.cpp
|
||||
@@ -89,12 +146,28 @@ lib boost_stacktrace_addr2line
|
||||
<warnings>all
|
||||
<target-os>linux:<library>dl
|
||||
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
[ check-target-builds ../build//addr2line : : <build>no ]
|
||||
<conditional>@build-stacktrace-addr2line
|
||||
: # default build
|
||||
: # usage-requirements
|
||||
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
<define>BOOST_STACKTRACE_NO_LIB=1
|
||||
;
|
||||
|
||||
rule build-stacktrace-basic ( props * )
|
||||
{
|
||||
local enabled = [ property.select <boost.stacktrace.basic> : $(props) ] ;
|
||||
switch $(enabled:G=)
|
||||
{
|
||||
case "on" : return ;
|
||||
case "off" : return <build>no ;
|
||||
}
|
||||
|
||||
if [ configure.builds WinDbg : $(props) : "boost.stacktrace.basic" ]
|
||||
{
|
||||
return <build>no ;
|
||||
}
|
||||
}
|
||||
|
||||
lib boost_stacktrace_basic
|
||||
: # sources
|
||||
../src/basic.cpp
|
||||
@@ -102,12 +175,28 @@ lib boost_stacktrace_basic
|
||||
<warnings>all
|
||||
<target-os>linux:<library>dl
|
||||
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
[ check-target-builds ../build//WinDbg : <build>no ]
|
||||
<conditional>@build-stacktrace-basic
|
||||
: # default build
|
||||
: # usage-requirements
|
||||
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
<define>BOOST_STACKTRACE_NO_LIB=1
|
||||
;
|
||||
|
||||
rule build-stacktrace-windbg ( props * )
|
||||
{
|
||||
local enabled = [ property.select <boost.stacktrace.windbg> : $(props) ] ;
|
||||
switch $(enabled:G=)
|
||||
{
|
||||
case "on" : return ;
|
||||
case "off" : return <build>no ;
|
||||
}
|
||||
|
||||
if ! [ configure.builds WinDbg : $(props) : "boost.stacktrace.windbg" ]
|
||||
{
|
||||
return <build>no ;
|
||||
}
|
||||
}
|
||||
|
||||
lib boost_stacktrace_windbg
|
||||
: # sources
|
||||
../src/windbg.cpp
|
||||
@@ -115,12 +204,28 @@ lib boost_stacktrace_windbg
|
||||
<warnings>all
|
||||
<library>Dbgeng <library>ole32
|
||||
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
[ check-target-builds ../build//WinDbg : : <build>no ]
|
||||
<conditional>@build-stacktrace-windbg
|
||||
: # default build
|
||||
: # usage-requirements
|
||||
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
<define>BOOST_STACKTRACE_NO_LIB=1
|
||||
;
|
||||
|
||||
rule build-stacktrace-windbg-cached ( props * )
|
||||
{
|
||||
local enabled = [ property.select <boost.stacktrace.windbg_cached> : $(props) ] ;
|
||||
switch $(enabled:G=)
|
||||
{
|
||||
case "on" : return ;
|
||||
case "off" : return <build>no ;
|
||||
}
|
||||
|
||||
if ! [ configure.builds WinDbgCached : $(props) : "boost.stacktrace.windbg_cached" ]
|
||||
{
|
||||
return <build>no ;
|
||||
}
|
||||
}
|
||||
|
||||
lib boost_stacktrace_windbg_cached
|
||||
: # sources
|
||||
../src/windbg_cached.cpp
|
||||
@@ -128,28 +233,42 @@ lib boost_stacktrace_windbg_cached
|
||||
<warnings>all
|
||||
<library>Dbgeng <library>ole32
|
||||
<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
[ check-target-builds ../build//WinDbgCached : : <build>no ]
|
||||
<conditional>@build-stacktrace-windbg-cached
|
||||
: # default build
|
||||
: # usage-requirements
|
||||
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
<define>BOOST_STACKTRACE_NO_LIB=1
|
||||
;
|
||||
|
||||
rule build-stacktrace-from-exception ( props * )
|
||||
{
|
||||
local enabled = [ property.select <boost.stacktrace.from_exception> : $(props) ] ;
|
||||
switch $(enabled:G=)
|
||||
{
|
||||
case "on" : return ;
|
||||
case "off" : return <build>no ;
|
||||
}
|
||||
|
||||
local arch = [ property.select <architecture> : $(props) ] ;
|
||||
if $(arch) && ( $(arch:G=) != x86 )
|
||||
{
|
||||
configure.log-library-search-result "boost.stacktrace.from_exception" : "no" ;
|
||||
return <build>no ;
|
||||
}
|
||||
configure.log-library-search-result "boost.stacktrace.from_exception" : "yes" ;
|
||||
}
|
||||
|
||||
lib boost_stacktrace_from_exception
|
||||
: # sources
|
||||
../src/from_exception.cpp
|
||||
: # requirements
|
||||
<warnings>all
|
||||
<target-os>linux:<library>dl
|
||||
<target-os>windows:<build>no # not supported at the moment
|
||||
|
||||
# Command line option to disable build
|
||||
<boost.stacktrace.from_exception>off:<build>no
|
||||
|
||||
# Require usable libbacktrace on other platforms
|
||||
[ check-target-builds ../build//libbacktrace : : <build>no ]
|
||||
# Enable build when explicitly requested, or by default, when on x86
|
||||
<conditional>@build-stacktrace-from-exception
|
||||
: # default build
|
||||
: # usage-requirements
|
||||
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
|
||||
<define>BOOST_STACKTRACE_NO_LIB=1
|
||||
;
|
||||
|
||||
boost-install boost_stacktrace_noop boost_stacktrace_backtrace boost_stacktrace_addr2line boost_stacktrace_basic boost_stacktrace_windbg boost_stacktrace_windbg_cached boost_stacktrace_from_exception ;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright Antony Polukhin, 2016-2024.
|
||||
# Copyright Antony Polukhin, 2016-2025.
|
||||
# Use, modification, and distribution are
|
||||
# subject to 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)
|
||||
@@ -9,9 +9,9 @@ import doxygen ;
|
||||
|
||||
doxygen autodoc
|
||||
:
|
||||
[ glob ../../../boost/stacktrace.hpp ]
|
||||
[ glob ../../../boost/stacktrace/*.hpp ]
|
||||
[ glob ../../../boost/stacktrace/detail/frame_decl.hpp ]
|
||||
[ glob ../include/boost/stacktrace.hpp ]
|
||||
[ glob ../include/boost/stacktrace/*.hpp ]
|
||||
[ glob ../include/boost/stacktrace/detail/frame_decl.hpp ]
|
||||
:
|
||||
<doxygen:param>EXTRACT_ALL=NO
|
||||
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[quickbook 1.6]
|
||||
[version 1.0]
|
||||
[id stacktrace]
|
||||
[copyright 2016-2024 Antony Polukhin]
|
||||
[copyright 2016-2025 Antony Polukhin]
|
||||
[category Language Features Emulation]
|
||||
[license
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -68,7 +68,7 @@ Pretty often assertions provide not enough information to locate the problem. Fo
|
||||
Aborted (core dumped)
|
||||
```
|
||||
|
||||
That's not enough to locate the problem without debugger. There may be thousand code lines in real world examples and hundred places where that assertion could happen. Let's try to improve the assertions, and make them more informative:
|
||||
That's not enough to locate the problem without debugger. There may be thousand code lines in real world examples and hundred places where that assertion can happen. Let's try to improve the assertions, and make them more informative:
|
||||
|
||||
[getting_started_assert_handlers]
|
||||
|
||||
@@ -137,7 +137,7 @@ See [link stacktrace.theoretical_async_signal_safety "Theoretical async signal s
|
||||
[section Stacktrace from arbitrary exception]
|
||||
|
||||
[warning At the moment the functionality is only available for some of the
|
||||
popular C++ runtimes for POSIX systems and requires *libbacktrace*.
|
||||
popular C++ runtimes for POSIX systems with *libbacktrace* and for Windows.
|
||||
Make sure that your platform is supported by running some tests.
|
||||
]
|
||||
|
||||
@@ -163,7 +163,7 @@ int main() {
|
||||
foo("test1");
|
||||
bar("test2");
|
||||
} catch (const std::exception& exc) {
|
||||
boost::stacktrace::stacktrace trace = std::stacktrace::from_current_exception(); // <---
|
||||
boost::stacktrace::stacktrace trace = boost::stacktrace::stacktrace::from_current_exception(); // <---
|
||||
std::cerr << "Caught exception: " << exc.what() << ", trace:\n" << trace;
|
||||
}
|
||||
}
|
||||
@@ -236,7 +236,7 @@ Code from above will output:
|
||||
|
||||
[section Enabling and disabling stacktraces]
|
||||
|
||||
At some point arises a requirement to easily enable/disable stacktraces for a whole project. That could be easily achieved.
|
||||
At some point arises a requirement to easily enable/disable stacktraces for a whole project. That can be easily achieved.
|
||||
|
||||
Just define *BOOST_STACKTRACE_LINK* for a whole project. Now you can enable/disable stacktraces by just linking with different libraries:
|
||||
|
||||
@@ -251,7 +251,7 @@ See [link stacktrace.configuration_and_build section "Configuration and Build"]
|
||||
[section Saving stacktraces by specified format]
|
||||
|
||||
[classref boost::stacktrace::stacktrace] provides access to individual [classref boost::stacktrace::frame frames] of the stacktrace,
|
||||
so that you could save stacktrace information in your own format. Consider the example, that saves only function addresses of each frame:
|
||||
so that you can save stacktrace information in your own format. Consider the example, that saves only function addresses of each frame:
|
||||
|
||||
[getting_started_trace_addresses]
|
||||
|
||||
@@ -304,7 +304,63 @@ Terminate called:
|
||||
|
||||
[section Configuration and Build]
|
||||
|
||||
By default Boost.Stacktrace is a header-only library, but you may change that and use the following macros to improve build times or to be able to tune library without recompiling your project:
|
||||
[section Usage from CMake]
|
||||
|
||||
CMake library `Boost::stacktrace` provides the best available implementation:
|
||||
|
||||
```
|
||||
target_link_libraries(${PROJECT}
|
||||
PUBLIC
|
||||
Boost::stacktrace
|
||||
)
|
||||
```
|
||||
|
||||
There are also CMake libraries for fine grained selection of implementation:
|
||||
|
||||
* `Boost::stacktrace_windbg`
|
||||
* `Boost::stacktrace_windbg_cached`
|
||||
* `Boost::stacktrace_backtrace`
|
||||
* `Boost::stacktrace_addr2line`
|
||||
* `Boost::stacktrace_basic`
|
||||
* `Boost::stacktrace_noop`
|
||||
|
||||
Note that `Boost::stacktrace_from_exception` is not used by default, so add it explicitly if its functionality is required:
|
||||
|
||||
```
|
||||
target_link_libraries(${PROJECT} # your project
|
||||
PUBLIC
|
||||
Boost::stacktrace
|
||||
Boost::stacktrace_from_exception
|
||||
)
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section CMake build notes]
|
||||
|
||||
When building the Boost.Stacktrace libraries using `CMake` the `BOOST_STACKTRACE_ENABLE_*` options control the build. For example:
|
||||
|
||||
* `cmake -DBOOST_STACKTRACE_ENABLE_NOOP=0 -DBOOST_STACKTRACE_ENABLE_BACKTRACE=1 -DBOOST_STACKTRACE_ENABLE_FROM_EXCEPTION=1` - do not build the `noop` implementation and force the builds of `backtrace` and `from_exception`.
|
||||
* `cmake -DBOOST_STACKTRACE_ENABLE_NOOP=1 -DBOOST_STACKTRACE_ENABLE_WINDBG=1 -DBOOST_STACKTRACE_ENABLE_WINDBG_CACHED=0` - build the `noop` and `windbg` implementations and disable the build of `windbg_cached`.
|
||||
|
||||
If options are not provided they are auto-detected and the result of detection is printed and implicitly used during build.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section B2 build notes]
|
||||
|
||||
When building the Boost.Stacktrace libraries using `b2` the `boost.stacktrace.*` options can be used to control the build. For example:
|
||||
|
||||
* `b2 boost.stacktrace.noop=off boost.stacktrace.backtrace=on boost.stacktrace.from_exception=on` - do not build the `noop` implementation and force the builds of `backtrace` and `from_exception`.
|
||||
* `b2 boost.stacktrace.noop=on boost.stacktrace.windbg=on boost.stacktrace.windbg_cached=off` - build the `noop` and `windbg` implementations and disable the build of `windbg_cached`.
|
||||
|
||||
If options are not provided they are auto-detected and the result of detection is printed and implicitly used during build.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Header only options]
|
||||
|
||||
If CMake is not used then the Boost.Stacktrace is a header-only library by default. To change that (to improve build times or to be able to tune library without recompiling your project) use the following macros:
|
||||
[table:linkmacro Link macros
|
||||
[[Macro name] [Effect]]
|
||||
[[*BOOST_STACKTRACE_LINK*] [Disable header-only build and require linking with shared or static library that contains the tracing implementation. If *BOOST_ALL_DYN_LINK* is defined, then link with shared library.]]
|
||||
@@ -312,13 +368,13 @@ By default Boost.Stacktrace is a header-only library, but you may change that an
|
||||
]
|
||||
|
||||
|
||||
In header only mode library could be tuned by macro. If one of the link macro from above is defined, you have to manually link with one of the libraries:
|
||||
In header only mode library can be tuned by macro. If one of the link macro from above is defined, you have to manually link with one of the libraries:
|
||||
[table:libconfig Config
|
||||
[[Macro name or default] [Library] [Effect] [Platforms] [Uses debug information [footnote This will provide more readable backtraces with *source code locations* if the binary is built with debug information.]] [Uses dynamic exports information [footnote This will provide readable function names in backtrace for functions that are exported by the binary. Compiling with `-rdynamic` flag, without `-fvisibility=hidden` or marking functions as exported produce a better stacktraces.]] ]
|
||||
[[['default for MSVC, Intel on Windows, MinGW-w64] / *BOOST_STACKTRACE_USE_WINDBG*] [*boost_stacktrace_windbg*] [ Uses `dbgeng.h` to show debug info, stores the implementation internals in a static varaible protected with mutex. May require linking with *ole32* and *dbgeng*. ] [MSVC, MinGW-w64, Intel on Windows] [yes] [no]]
|
||||
[[['default for MSVC, Intel on Windows, MinGW-w64] / *BOOST_STACKTRACE_USE_WINDBG*] [*boost_stacktrace_windbg*] [ Uses `dbgeng.h` to show debug info, stores the implementation internals in a static variable protected with mutex. May require linking with *ole32* and *dbgeng*. ] [MSVC, MinGW-w64, Intel on Windows] [yes] [no]]
|
||||
[[['default for other platforms]] [*boost_stacktrace_basic*] [Uses compiler intrinsics to collect stacktrace and if possible `::dladdr` to show information about the symbol. Requires linking with *libdl* library on POSIX platforms.] [Any compiler on POSIX or MinGW] [no] [yes]]
|
||||
[[*BOOST_STACKTRACE_USE_WINDBG_CACHED*] [*boost_stacktrace_windbg_cached*] [ Uses `dbgeng.h` to show debug info and caches implementation internals in TLS for better performance. Useful only for cases when traces are gathered very often. May require linking with *ole32* and *dbgeng*. ] [MSVC, Intel on Windows] [yes] [no]]
|
||||
[[*BOOST_STACKTRACE_USE_BACKTRACE*] [*boost_stacktrace_backtrace*] [Requires linking with *libdl* on POSIX and *libbacktrace* libraries[footnote Some *libbacktrace* packages SEGFAULT if there's a concurrent work with the same `backtrace_state` instance. To avoid that issue the Boost.Stacktrace library uses `thread_local` states, unfortunately this may consume a lot of memory if you often create and destroy execution threads in your application. Define *BOOST_STACKTRACE_BACKTRACE_FORCE_STATIC* to force single instance, but make sure that [@https://github.com/boostorg/stacktrace/blob/develop/test/thread_safety_checking.cpp thread_safety_checking.cpp] works well in your setup. ]. *libbacktrace* is probably already installed in your system[footnote If you are using Clang with libstdc++ you could get into troubles of including `<backtrace.h>`, because on some platforms Clang does not search for headers in the GCC's include paths and any attempt to add GCC's include path leads to linker errors. To explicitly specify a path to the `<backtrace.h>` header you could define the *BOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE* to a full path to the header. For example on Ubuntu Xenial use the command line option *-DBOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE=</usr/lib/gcc/x86_64-linux-gnu/5/include/backtrace.h>* while building with Clang. ], or built into your compiler.
|
||||
[[*BOOST_STACKTRACE_USE_BACKTRACE*] [*boost_stacktrace_backtrace*] [Requires linking with *libdl* on POSIX and *libbacktrace* libraries[footnote Some *libbacktrace* packages SEGFAULT if there's a concurrent work with the same `backtrace_state` instance. To avoid that issue the Boost.Stacktrace library uses `thread_local` states, unfortunately this may consume a lot of memory if you often create and destroy execution threads in your application. Define *BOOST_STACKTRACE_BACKTRACE_FORCE_STATIC* to force single instance, but make sure that [@https://github.com/boostorg/stacktrace/blob/develop/test/thread_safety_checking.cpp thread_safety_checking.cpp] works well in your setup. ]. *libbacktrace* is probably already installed in your system[footnote If you are using Clang with libstdc++ you can get into troubles of including `<backtrace.h>`, because on some platforms Clang does not search for headers in the GCC's include paths and any attempt to add GCC's include path leads to linker errors. To explicitly specify a path to the `<backtrace.h>` header you can define the *BOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE* to a full path to the header. For example on Ubuntu Xenial use the command line option *-DBOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE=</usr/lib/gcc/x86_64-linux-gnu/5/include/backtrace.h>* while building with Clang. ], or built into your compiler.
|
||||
|
||||
Otherwise (if you are a *MinGW*/*MinGW-w64* user for example) it can be downloaded [@https://github.com/ianlancetaylor/libbacktrace from here] or [@https://github.com/gcc-mirror/gcc/tree/master/libbacktrace from here]. ] [Any compiler on POSIX, or MinGW, or MinGW-w64] [yes] [yes]]
|
||||
[[*BOOST_STACKTRACE_USE_ADDR2LINE*] [*boost_stacktrace_addr2line*] [Use *addr2line* program to retrieve stacktrace. Requires linking with *libdl* library and `::fork` system call. Macro *BOOST_STACKTRACE_ADDR2LINE_LOCATION* must be defined to the absolute path to the addr2line executable if it is not located in /usr/bin/addr2line. ] [Any compiler on POSIX] [yes] [yes]]
|
||||
@@ -331,6 +387,8 @@ In header only mode library could be tuned by macro. If one of the link macro fr
|
||||
* if you wish to disable backtracing and *BOOST_STACKTRACE_LINK* is defined, you just need link with *-lboost_stacktrace_noop*
|
||||
* if you wish to disable backtracing and you use the library in header only mode, you just need to define *BOOST_STACKTRACE_USE_NOOP* for the whole project and recompile it
|
||||
|
||||
[endsect]
|
||||
|
||||
[section MinGW and MinGW-w64 specific notes]
|
||||
|
||||
MinGW-w64 and MinGW (without -w64) users have to install libbacktrace for getting better stacktraces. Follow the instruction:
|
||||
@@ -370,11 +428,11 @@ In theory, walking the stack without decoding and demangling should be async sig
|
||||
In practice, it is not:
|
||||
|
||||
* Looks like a page fault while dumping the trace on a containerized/virtualized
|
||||
Windows system has a chance to deadlock. Page fault could happen easily
|
||||
Windows system has a chance to deadlock. Page fault can happen easily
|
||||
as we have to write the dump either to memory or to a file.
|
||||
* On POSIX systems a deadlock could happen if a signal is received when throwing
|
||||
* On POSIX systems a deadlock can happen if a signal is received when throwing
|
||||
an exception [@https://github.com/boostorg/stacktrace/issues/131 #131].
|
||||
Theoretically this could be worked around by bypassing the mutex locking
|
||||
Theoretically this can be worked around by bypassing the mutex locking
|
||||
in C++-runtime at exception throw
|
||||
([@https://github.com/userver-framework/userver/blob/4246909c99506d3ab34bd130a5154b4acc8e87de/core/src/engine/task/exception_hacks.cpp#L241-L244 sample implementation]
|
||||
in the 🐙 userver framework), or by using a very modern runtime
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// 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)
|
||||
|
||||
#define BOOST_USER_CONFIG <libs/stacktrace/example/user_config.hpp>
|
||||
#define BOOST_USER_CONFIG <example/user_config.hpp>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <exception> // std::set_terminate, std::abort
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/stacktrace/detail/try_dec_convert.hpp>
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
@@ -116,12 +117,14 @@ inline std::string addr2line(const char* flag, const void* addr) {
|
||||
std::string res;
|
||||
|
||||
boost::stacktrace::detail::location_from_symbol loc(addr);
|
||||
if (!loc.empty()) {
|
||||
// For programs started through $PATH loc.name() is not absolute and
|
||||
// addr2line will fail.
|
||||
if (!loc.empty() && std::strchr(loc.name(), '/') != nullptr) {
|
||||
res = loc.name();
|
||||
} else {
|
||||
res.resize(16);
|
||||
int rlin_size = ::readlink("/proc/self/exe", &res[0], res.size() - 1);
|
||||
while (rlin_size == static_cast<int>(res.size() - 1)) {
|
||||
ssize_t rlin_size = ::readlink("/proc/self/exe", &res[0], res.size() - 1);
|
||||
while (rlin_size == static_cast<ssize_t>(res.size() - 1)) {
|
||||
res.resize(res.size() * 4);
|
||||
rlin_size = ::readlink("/proc/self/exe", &res[0], res.size() - 1);
|
||||
}
|
||||
@@ -129,7 +132,7 @@ inline std::string addr2line(const char* flag, const void* addr) {
|
||||
res.clear();
|
||||
return res;
|
||||
}
|
||||
res.resize(rlin_size);
|
||||
res.resize(static_cast<std::size_t>(rlin_size));
|
||||
}
|
||||
|
||||
addr2line_pipe p(flag, res.c_str(), to_hex_array(addr).data());
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
72
include/boost/stacktrace/detail/addr_base_msvc.hpp
Normal file
72
include/boost/stacktrace/detail/addr_base_msvc.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// 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_ADDR_BASE_MSVC_HPP
|
||||
#define BOOST_STACKTRACE_DETAIL_ADDR_BASE_MSVC_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
|
||||
#ifdef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#else
|
||||
// Prevent inclusion of extra Windows SDK headers which can cause conflict
|
||||
// with other code using Windows SDK
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
namespace boost { namespace stacktrace { namespace detail {
|
||||
inline std::uintptr_t get_own_proc_addr_base(const void* addr) {
|
||||
// Try to avoid allocating memory for the modules array if possible.
|
||||
// The stack buffer should be large enough for most processes.
|
||||
HMODULE modules_stack[1024];
|
||||
std::unique_ptr<HMODULE[]> modules_allocated;
|
||||
HMODULE* modules = modules_stack;
|
||||
|
||||
DWORD needed_bytes = 0;
|
||||
std::uintptr_t addr_base = 0;
|
||||
|
||||
HANDLE process_handle = GetCurrentProcess();
|
||||
auto enum_process_is_ok = EnumProcessModules(process_handle, modules, sizeof(modules), &needed_bytes);
|
||||
|
||||
// Check if the error is because the buffer is too small.
|
||||
if (!enum_process_is_ok && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
modules_allocated.reset(new HMODULE[needed_bytes / sizeof(HMODULE)]);
|
||||
modules = modules_allocated.get();
|
||||
enum_process_is_ok = EnumProcessModules(process_handle, modules, needed_bytes, &needed_bytes);
|
||||
}
|
||||
|
||||
if (enum_process_is_ok) {
|
||||
for (std::size_t i = 0; i < (needed_bytes / sizeof(HMODULE)); ++i) {
|
||||
MODULEINFO module_info;
|
||||
|
||||
// Get the module name
|
||||
if (GetModuleInformation(process_handle, modules[i], &module_info, sizeof(module_info))
|
||||
&& module_info.lpBaseOfDll <= addr && addr < LPBYTE(module_info.lpBaseOfDll) + module_info.SizeOfImage) {
|
||||
// Module contains the address
|
||||
addr_base = reinterpret_cast<std::uintptr_t>(module_info.lpBaseOfDll);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(process_handle);
|
||||
|
||||
return addr_base;
|
||||
}
|
||||
|
||||
}}} // namespace boost::stacktrace::detail
|
||||
|
||||
#endif // BOOST_STACKTRACE_DETAIL_ADDR_BASE_MSVC_HPP
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -88,7 +88,7 @@ std::size_t this_thread_frames::collect(native_frame_ptr_t* out_frames, std::siz
|
||||
#else
|
||||
boost::stacktrace::detail::unwind_state state = { skip, out_frames, out_frames + max_frames_count };
|
||||
::_Unwind_Backtrace(&boost::stacktrace::detail::unwind_callback, &state);
|
||||
frames_count = state.current - out_frames;
|
||||
frames_count = static_cast<std::size_t>(state.current - out_frames);
|
||||
#endif //defined(BOOST_STACKTRACE_USE_LIBC_BACKTRACE_FUNCTION)
|
||||
|
||||
if (frames_count && out_frames[frames_count - 1] == 0) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -18,12 +18,26 @@
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/stacktrace/detail/to_dec_array.hpp>
|
||||
#include <boost/stacktrace/detail/to_hex_array.hpp>
|
||||
|
||||
#ifndef BOOST_STACKTRACE_DISABLE_OFFSET_ADDR_BASE
|
||||
#include <boost/stacktrace/detail/addr_base_msvc.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
// Prevent inclusion of extra Windows SDK headers which can cause conflict
|
||||
// with other code using Windows SDK
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include "dbgeng.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#if defined(__clang__) || defined(BOOST_MSVC)
|
||||
# pragma comment(lib, "ole32.lib")
|
||||
# pragma comment(lib, "Dbgeng.lib")
|
||||
#endif
|
||||
@@ -237,6 +251,57 @@ public:
|
||||
const std::size_t delimiter = result.find_first_of('!');
|
||||
if (module_name) {
|
||||
*module_name = result.substr(0, delimiter);
|
||||
if (!module_name->empty()) {
|
||||
ULONG64 base = 0;
|
||||
res = (S_OK == idebug_->GetModuleByOffset(
|
||||
offset,
|
||||
0,
|
||||
nullptr,
|
||||
&base
|
||||
));
|
||||
|
||||
if (res) {
|
||||
name[0] = '\0';
|
||||
size = 0;
|
||||
res = (S_OK == idebug_->GetModuleNames(
|
||||
DEBUG_ANY_ID,
|
||||
base,
|
||||
name,
|
||||
sizeof(name),
|
||||
&size,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr
|
||||
));
|
||||
}
|
||||
|
||||
if (!res && size != 0)
|
||||
{
|
||||
std::string module_path(size, char());
|
||||
res = (S_OK == idebug_->GetModuleNames(
|
||||
DEBUG_ANY_ID,
|
||||
base,
|
||||
&module_path[0],
|
||||
static_cast<ULONG>(module_path.size()),
|
||||
&size,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr
|
||||
));
|
||||
if (res && size > 1) {
|
||||
module_name->assign(module_path, size - 1);
|
||||
}
|
||||
}
|
||||
else if (res && size > 1) {
|
||||
module_name->assign(name, size - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (delimiter == std::string::npos) {
|
||||
@@ -330,7 +395,13 @@ public:
|
||||
if (!name.empty()) {
|
||||
res += name;
|
||||
} else {
|
||||
#ifdef BOOST_STACKTRACE_DISABLE_OFFSET_ADDR_BASE
|
||||
res += to_hex_array(addr).data();
|
||||
#else
|
||||
// Get own base address
|
||||
const uintptr_t base_addr = get_own_proc_addr_base(addr);
|
||||
res += to_hex_array(reinterpret_cast<uintptr_t>(addr) - base_addr).data();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::pair<std::string, std::size_t> source_line = this->get_source_file_line_impl(addr);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <boost/stacktrace/detail/to_hex_array.hpp>
|
||||
#include <boost/stacktrace/detail/location_from_symbol.hpp>
|
||||
#include <boost/stacktrace/detail/to_dec_array.hpp>
|
||||
#include <boost/stacktrace/detail/addr_base.hpp>
|
||||
#include <boost/core/demangle.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
@@ -40,7 +41,12 @@ public:
|
||||
if (!Base::res.empty()) {
|
||||
Base::res = boost::core::demangle(Base::res.c_str());
|
||||
} else {
|
||||
#ifdef BOOST_STACKTRACE_DISABLE_OFFSET_ADDR_BASE
|
||||
Base::res = to_hex_array(addr).data();
|
||||
#else
|
||||
const auto addr_base = boost::stacktrace::detail::get_own_proc_addr_base(addr);
|
||||
Base::res = to_hex_array(reinterpret_cast<uintptr_t>(addr) - addr_base).data();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (Base::prepare_source_location(addr)) {
|
||||
@@ -90,8 +96,8 @@ std::string frame::name() const {
|
||||
}
|
||||
|
||||
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
|
||||
::Dl_info dli;
|
||||
const bool dl_ok = !!::dladdr(const_cast<void*>(addr_), &dli); // `dladdr` on Solaris accepts nonconst addresses
|
||||
boost::stacktrace::detail::Dl_info dli;
|
||||
const bool dl_ok = !!boost::stacktrace::detail::dladdr(addr_, dli);
|
||||
if (dl_ok && dli.dli_sname) {
|
||||
return boost::core::demangle(dli.dli_sname);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -52,7 +52,7 @@ inline int libbacktrace_full_callback(void *data, uintptr_t /*pc*/, const char *
|
||||
if (d.function && function) {
|
||||
*d.function = function;
|
||||
}
|
||||
d.line = lineno;
|
||||
d.line = static_cast<std::size_t>(lineno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -18,17 +18,110 @@
|
||||
# include <boost/winapi/dll.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
/* AIX doesn't provide dladdr syscall.
|
||||
This provides a minimal implementation of dladdr which retrieves
|
||||
only files information.
|
||||
TODO: Implement the symbol name. */
|
||||
|
||||
#include <sys/ldr.h>
|
||||
#include <sys/debug.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace stacktrace { namespace detail {
|
||||
|
||||
struct Dl_info {
|
||||
std::string fname_storage{};
|
||||
const char *dli_fname = nullptr;
|
||||
const char *dli_sname = nullptr;
|
||||
};
|
||||
|
||||
int dladdr(const void* address_raw, Dl_info* info) noexcept {
|
||||
static constexpr std::size_t dl_buff_size = 0x1000;
|
||||
|
||||
try {
|
||||
std::vector<struct ld_info> pld_info_storage;
|
||||
pld_info_storage.resize(
|
||||
(dl_buff_size + sizeof(struct ld_info) - 1) / sizeof(struct ld_info)
|
||||
);
|
||||
|
||||
if (loadquery(L_GETINFO, pld_info_storage.data(), dl_buff_size) == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto* pld_info = pld_info_storage.data();
|
||||
const char* const address = static_cast<const char*>(address_raw);
|
||||
while (true) {
|
||||
const auto* const dataorg = static_cast<char*>(pld_info->ldinfo_dataorg);
|
||||
const auto* const textorg = static_cast<char*>(pld_info->ldinfo_textorg);
|
||||
if ((address >= dataorg && address < dataorg + pld_info->ldinfo_datasize )
|
||||
|| (address >= textorg && address < textorg + pld_info->ldinfo_textsize )) {
|
||||
|
||||
/* ldinfo_filename is the null-terminated path name followed
|
||||
by null-terminated member name.
|
||||
If the file is not an archive, then member name is null. */
|
||||
const auto size_filename = std::strlen(pld_info->ldinfo_filename);
|
||||
const auto size_member = std::strlen(pld_info->ldinfo_filename + size_filename + 1);
|
||||
|
||||
/* If member is not null, '(' and ')' must be added to create a
|
||||
fname looking like "filename(membername)". */
|
||||
info->fname_storage.reserve(size_filename + (size_member ? size_member + 3 : 1));
|
||||
info->fname_storage = pld_info->ldinfo_filename;
|
||||
if (size_member) {
|
||||
info->fname_storage += "(";
|
||||
info->fname_storage += pld_info->ldinfo_filename + size_filename + 1;
|
||||
info->fname_storage += ")";
|
||||
}
|
||||
|
||||
info->dli_fname = info->fname_storage.c_str();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!pld_info->ldinfo_next) {
|
||||
break;
|
||||
}
|
||||
|
||||
pld_info = reinterpret_cast<const struct ld_info *>(
|
||||
reinterpret_cast<const char*>(pld_info) + pld_info->ldinfo_next
|
||||
);
|
||||
};
|
||||
} catch (...) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}}} // namespace boost::stacktrace::detail
|
||||
|
||||
#elif !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
|
||||
|
||||
namespace boost { namespace stacktrace { namespace detail {
|
||||
|
||||
using Dl_info = ::Dl_info;
|
||||
|
||||
inline int dladdr(const void* addr, Dl_info& dli) noexcept {
|
||||
// `dladdr` on Solaris accepts nonconst addresses
|
||||
return ::dladdr(const_cast<void*>(addr), &dli);
|
||||
}
|
||||
|
||||
}}} // namespace boost::stacktrace::detail
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost { namespace stacktrace { namespace detail {
|
||||
|
||||
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
|
||||
class location_from_symbol {
|
||||
::Dl_info dli_;
|
||||
boost::stacktrace::detail::Dl_info dli_;
|
||||
|
||||
public:
|
||||
explicit location_from_symbol(const void* addr) noexcept
|
||||
: dli_()
|
||||
{
|
||||
if (!::dladdr(const_cast<void*>(addr), &dli_)) { // `dladdr` on Solaris accepts nonconst addresses
|
||||
if (!boost::stacktrace::detail::dladdr(addr, dli_)) {
|
||||
dli_.dli_fname = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -11,7 +11,11 @@
|
||||
# define BOOST_STACKTRACE_LINK
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_STACKTRACE_LINK) && !defined(BOOST_STACKTRACE_DYN_LINK) && defined(BOOST_ALL_DYN_LINK)
|
||||
#if !defined(BOOST_STACKTRACE_LINK) && defined(BOOST_STACKTRACE_STATIC_LINK)
|
||||
# define BOOST_STACKTRACE_LINK
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_STACKTRACE_LINK) && !defined(BOOST_STACKTRACE_DYN_LINK) && !defined(BOOST_STACKTRACE_STATIC_LINK) && defined(BOOST_ALL_DYN_LINK)
|
||||
# define BOOST_STACKTRACE_DYN_LINK
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
|
||||
// Copyright Antony Polukhin, 2015-2024.
|
||||
// Copyright Antony Polukhin, 2015-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -20,6 +20,20 @@
|
||||
#include <boost/stacktrace/detail/frame_decl.hpp>
|
||||
#include <boost/stacktrace/detail/push_options.h>
|
||||
|
||||
#if defined(BOOST_MSVC) && (defined(BOOST_STACKTRACE_INTERNAL_BUILD_LIBS) || !defined(BOOST_STACKTRACE_LINK))
|
||||
extern "C" {
|
||||
|
||||
#if defined(BOOST_STACKTRACE_DYN_LINK)
|
||||
BOOST_SYMBOL_EXPORT
|
||||
#elif defined(BOOST_STACKTRACE_LINK)
|
||||
#else
|
||||
BOOST_SYMBOL_EXPORT inline
|
||||
#endif
|
||||
void* boost_stacktrace_impl_return_nullptr() { return nullptr; }
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boost { namespace stacktrace {
|
||||
|
||||
/// Comparison operators that provide platform dependant ordering and have O(1) complexity; are Async-Handler-Safe.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -35,7 +35,7 @@ namespace boost { namespace stacktrace {
|
||||
/// @cond
|
||||
namespace detail {
|
||||
|
||||
typedef const void* native_frame_ptr_t; // TODO: change to `typedef void(*native_frame_ptr_t)();`
|
||||
using native_frame_ptr_t = const void*;
|
||||
enum helper{ max_frames_dump = 128 };
|
||||
|
||||
BOOST_STACKTRACE_FUNCTION std::size_t from_dump(const char* filename, native_frame_ptr_t* out_frames);
|
||||
@@ -52,7 +52,7 @@ struct this_thread_frames { // struct is required to avoid warning about usage o
|
||||
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;
|
||||
|
||||
BOOST_NOINLINE static std::size_t safe_dump_to_impl(void* memory, std::size_t size, std::size_t skip) noexcept {
|
||||
typedef boost::stacktrace::detail::native_frame_ptr_t native_frame_ptr_t;
|
||||
using boost::stacktrace::detail::native_frame_ptr_t;
|
||||
|
||||
if (size < sizeof(native_frame_ptr_t)) {
|
||||
return 0;
|
||||
@@ -66,7 +66,7 @@ struct this_thread_frames { // struct is required to avoid warning about usage o
|
||||
|
||||
template <class T>
|
||||
BOOST_NOINLINE static std::size_t safe_dump_to_impl(T file, std::size_t skip, std::size_t max_depth) noexcept {
|
||||
typedef boost::stacktrace::detail::native_frame_ptr_t native_frame_ptr_t;
|
||||
using boost::stacktrace::detail::native_frame_ptr_t;
|
||||
|
||||
native_frame_ptr_t buffer[boost::stacktrace::detail::max_frames_dump + 1];
|
||||
if (max_depth > boost::stacktrace::detail::max_frames_dump) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -33,6 +33,25 @@
|
||||
# pragma warning(disable:2196) // warning #2196: routine is both "inline" and "noinline"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
|
||||
extern "C" {
|
||||
|
||||
const char* boost_stacktrace_impl_current_exception_stacktrace();
|
||||
bool* boost_stacktrace_impl_ref_capture_stacktraces_at_throw();
|
||||
|
||||
}
|
||||
|
||||
#ifdef _M_IX86
|
||||
# pragma comment(linker, "/ALTERNATENAME:_boost_stacktrace_impl_current_exception_stacktrace=_boost_stacktrace_impl_return_nullptr")
|
||||
# pragma comment(linker, "/ALTERNATENAME:_boost_stacktrace_impl_ref_capture_stacktraces_at_throw=_boost_stacktrace_impl_return_nullptr")
|
||||
#else
|
||||
# pragma comment(linker, "/ALTERNATENAME:boost_stacktrace_impl_current_exception_stacktrace=boost_stacktrace_impl_return_nullptr")
|
||||
# pragma comment(linker, "/ALTERNATENAME:boost_stacktrace_impl_ref_capture_stacktraces_at_throw=boost_stacktrace_impl_return_nullptr")
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost { namespace stacktrace {
|
||||
|
||||
namespace impl {
|
||||
@@ -381,6 +400,8 @@ public:
|
||||
if (impl::current_exception_stacktrace) {
|
||||
trace = impl::current_exception_stacktrace();
|
||||
}
|
||||
#elif defined(BOOST_MSVC)
|
||||
trace = boost_stacktrace_impl_current_exception_stacktrace();
|
||||
#endif
|
||||
|
||||
if (trace) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2023-2024.
|
||||
// Copyright Antony Polukhin, 2023-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -27,6 +27,10 @@ inline void set_capture_stacktraces_at_throw(bool enable = true) noexcept {
|
||||
if (impl::ref_capture_stacktraces_at_throw) {
|
||||
impl::ref_capture_stacktraces_at_throw() = enable;
|
||||
}
|
||||
#elif defined(BOOST_MSVC)
|
||||
if (bool* p = boost_stacktrace_impl_ref_capture_stacktraces_at_throw()) {
|
||||
*p = enable;
|
||||
}
|
||||
#endif
|
||||
(void)enable;
|
||||
}
|
||||
@@ -45,6 +49,10 @@ inline bool get_capture_stacktraces_at_throw() noexcept {
|
||||
if (impl::ref_capture_stacktraces_at_throw) {
|
||||
return impl::ref_capture_stacktraces_at_throw();
|
||||
}
|
||||
#elif defined(BOOST_MSVC)
|
||||
if (bool* p = boost_stacktrace_impl_ref_capture_stacktraces_at_throw()) {
|
||||
return *p;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2023-2024.
|
||||
// Copyright Antony Polukhin, 2023-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,9 +1,150 @@
|
||||
// Copyright Antony Polukhin, 2023-2024.
|
||||
// Copyright Antony Polukhin, 2023-2025.
|
||||
//
|
||||
// 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)
|
||||
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
|
||||
#include <boost/stacktrace/safe_dump_to.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
extern "C" void** __cdecl __current_exception(); // exported from vcruntime.dll
|
||||
#define _pCurrentException static_cast<PEXCEPTION_RECORD>(*__current_exception())
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr std::size_t kStacktraceDumpSize = 4096;
|
||||
|
||||
struct thrown_info {
|
||||
ULONG_PTR object;
|
||||
char* dump;
|
||||
};
|
||||
|
||||
struct exception_data {
|
||||
bool capture_stacktraces_at_throw = true;
|
||||
unsigned count = 0;
|
||||
thrown_info* info = nullptr;
|
||||
|
||||
~exception_data() noexcept {
|
||||
HANDLE hHeap = GetProcessHeap();
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
HeapFree(hHeap, 0, info[i].dump);
|
||||
}
|
||||
HeapFree(hHeap, 0, info);
|
||||
}
|
||||
};
|
||||
|
||||
thread_local exception_data data;
|
||||
|
||||
inline bool PER_IS_MSVC_EH(PEXCEPTION_RECORD p) noexcept {
|
||||
const DWORD EH_EXCEPTION_NUMBER = 0xE06D7363;
|
||||
const ULONG_PTR EH_MAGIC_NUMBER1 = 0x19930520;
|
||||
|
||||
return p->ExceptionCode == EH_EXCEPTION_NUMBER &&
|
||||
(p->NumberParameters == 3 || p->NumberParameters == 4) &&
|
||||
p->ExceptionInformation[0] == EH_MAGIC_NUMBER1;
|
||||
}
|
||||
|
||||
inline ULONG_PTR PER_PEXCEPTOBJ(PEXCEPTION_RECORD p) noexcept {
|
||||
return p->ExceptionInformation[1];
|
||||
}
|
||||
|
||||
unsigned current_cxx_exception_index() noexcept {
|
||||
if (PEXCEPTION_RECORD current_cxx_exception = _pCurrentException) {
|
||||
for (unsigned i = data.count; i > 0;) {
|
||||
--i;
|
||||
if (data.info[i].object == PER_PEXCEPTOBJ(current_cxx_exception)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return data.count;
|
||||
}
|
||||
|
||||
bool is_processing_rethrow(PEXCEPTION_RECORD p) noexcept {
|
||||
// Processing flow:
|
||||
// 0. throw;
|
||||
// 1. _CxxThrowException(pExceptionObject = nullptr)
|
||||
// 2. VEH & SEH (may throw new c++ exceptions!)
|
||||
// 3. __RethrowException(_pCurrentException)
|
||||
// 4. VEH
|
||||
if (PER_PEXCEPTOBJ(p) == 0) return true;
|
||||
PEXCEPTION_RECORD current_cxx_exception = _pCurrentException;
|
||||
if (current_cxx_exception == nullptr) return false;
|
||||
return PER_PEXCEPTOBJ(p) == PER_PEXCEPTOBJ(current_cxx_exception);
|
||||
}
|
||||
|
||||
LONG NTAPI veh(PEXCEPTION_POINTERS p) {
|
||||
if (data.capture_stacktraces_at_throw &&
|
||||
PER_IS_MSVC_EH(p->ExceptionRecord) &&
|
||||
!is_processing_rethrow(p->ExceptionRecord)) {
|
||||
HANDLE hHeap = GetProcessHeap();
|
||||
unsigned index = current_cxx_exception_index();
|
||||
unsigned new_count = 1 + (index < data.count ? index + 1 : 0);
|
||||
|
||||
for (unsigned i = new_count; i < data.count; ++i) {
|
||||
HeapFree(hHeap, 0, data.info[i].dump);
|
||||
data.info[i].dump = nullptr;
|
||||
}
|
||||
|
||||
void* new_info;
|
||||
if (data.info) {
|
||||
new_info = HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, data.info, sizeof(thrown_info) * new_count);
|
||||
} else {
|
||||
new_info = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(thrown_info) * new_count);
|
||||
}
|
||||
if (new_info) {
|
||||
data.count = new_count;
|
||||
data.info = static_cast<thrown_info*>(new_info);
|
||||
data.info[data.count - 1].object = PER_PEXCEPTOBJ(p->ExceptionRecord);
|
||||
char*& dump_ptr = data.info[data.count - 1].dump;
|
||||
if (dump_ptr == nullptr) {
|
||||
dump_ptr = static_cast<char*>(HeapAlloc(hHeap, 0, kStacktraceDumpSize));
|
||||
}
|
||||
if (dump_ptr != nullptr) {
|
||||
const std::size_t kSkip = 4;
|
||||
boost::stacktrace::safe_dump_to(kSkip, dump_ptr, kStacktraceDumpSize);
|
||||
}
|
||||
} else if (new_count <= data.count) {
|
||||
data.count = new_count - 1;
|
||||
HeapFree(hHeap, 0, data.info[data.count - 1].dump);
|
||||
data.info[data.count - 1].dump = nullptr;
|
||||
}
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
struct veh_installer {
|
||||
PVOID h;
|
||||
veh_installer() noexcept : h(AddVectoredExceptionHandler(1, veh)) {}
|
||||
~veh_installer() noexcept { RemoveVectoredExceptionHandler(h); }
|
||||
} installer;
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
BOOST_SYMBOL_EXPORT const char* boost_stacktrace_impl_current_exception_stacktrace() {
|
||||
unsigned index = current_cxx_exception_index();
|
||||
return index < data.count ? data.info[index].dump : nullptr;
|
||||
}
|
||||
|
||||
BOOST_SYMBOL_EXPORT bool* boost_stacktrace_impl_ref_capture_stacktraces_at_throw() {
|
||||
return &data.capture_stacktraces_at_throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace boost { namespace stacktrace { namespace impl {
|
||||
|
||||
BOOST_SYMBOL_EXPORT void assert_no_pending_traces() noexcept {
|
||||
}
|
||||
|
||||
}}} // namespace boost::stacktrace::impl
|
||||
|
||||
#else
|
||||
|
||||
#include "exception_headers.h"
|
||||
|
||||
// At the moment the file is used only on POSIX. _Unwind_Backtrace may be
|
||||
@@ -16,6 +157,7 @@
|
||||
#include <boost/stacktrace/safe_dump_to.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <exception>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#if !BOOST_STACKTRACE_ALWAYS_STORE_IN_PADDING
|
||||
@@ -92,7 +234,7 @@ static const char*& reference_to_empty_padding(void* ptr) noexcept {
|
||||
if (is_libcpp_runtime()) {
|
||||
// libc++-runtime
|
||||
BOOST_ASSERT_MSG(
|
||||
sizeof(void*) == 4,
|
||||
sizeof(void*) != 4,
|
||||
"32bit platforms are unsupported with libc++ runtime padding reusage. "
|
||||
"Please report this issue to the library maintainters."
|
||||
);
|
||||
@@ -222,3 +364,4 @@ BOOST_SYMBOL_EXPORT void assert_no_pending_traces() noexcept {
|
||||
|
||||
}}} // namespace boost::stacktrace::impl
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
|
||||
#define BOOST_STACKTRACE_LINK
|
||||
#include <boost/stacktrace/detail/frame_msvc.ipp>
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#define BOOST_STACKTRACE_INTERNAL_BUILD_LIBS
|
||||
#define BOOST_STACKTRACE_LINK
|
||||
#define BOOST_STACKTRACE_USE_WINDBG_CACHED
|
||||
|
||||
14
test/CMakeLists.txt
Normal file
14
test/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
# Copyright 2018-2020 Peter Dimov
|
||||
# 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(BoostTest OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
|
||||
|
||||
if(NOT HAVE_BOOST_TEST)
|
||||
return()
|
||||
endif()
|
||||
|
||||
boost_test(TYPE run SOURCES test.cpp test_impl.cpp LINK_LIBRARIES Boost::stacktrace Boost::core)
|
||||
boost_test(TYPE run SOURCES test_noop.cpp test_impl.cpp LINK_LIBRARIES Boost::stacktrace_noop Boost::core)
|
||||
|
||||
boost_test(TYPE run SOURCES test_trivial.cpp LINK_LIBRARIES Boost::stacktrace Boost::core)
|
||||
@@ -5,7 +5,9 @@
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
|
||||
import ../../config/checks/config : requires ;
|
||||
import-search /boost/config/checks ;
|
||||
import config : requires ;
|
||||
import testing ;
|
||||
|
||||
lib dl : : <link>shared ;
|
||||
lib gcc_s ;
|
||||
@@ -24,13 +26,15 @@ lib backtrace
|
||||
|
||||
project
|
||||
: requirements
|
||||
[ requires cxx11_rvalue_references ]
|
||||
[ requires cxx11_rvalue_references cxx11_template_aliases cxx11_noexcept ]
|
||||
<toolset>msvc:<asynch-exceptions>on
|
||||
<toolset>intel:<cxxflags>-wd2196
|
||||
<target-os>linux:<linkflags>-lpthread
|
||||
<warnings>all
|
||||
<test-info>always_show_run_output
|
||||
<visibility>hidden
|
||||
<include>..
|
||||
<library>/boost/optional//boost_optional
|
||||
;
|
||||
|
||||
local FORCE_SYMBOL_EXPORT = <target-os>freebsd:<linkflags>"-rdynamic" <target-os>solaris:<linkflags>"-Bdynamic" <target-os>aix:<linkflags>"-rdynamic"
|
||||
@@ -122,15 +126,19 @@ test-suite stacktrace_tests
|
||||
[ run thread_safety_checking.cpp
|
||||
: : : <debug-symbols>on <library>.//test_impl_lib_backtrace $(LINKSHARED_BT)
|
||||
<define>BOOST_STACKTRACE_BACKTRACE_FORCE_STATIC
|
||||
<library>/boost/optional//boost_optional
|
||||
: backtrace_lib_threaded_static ]
|
||||
[ run thread_safety_checking.cpp
|
||||
: : : <debug-symbols>on <library>.//test_impl_lib_windbg $(LINKSHARED_WIND)
|
||||
<library>/boost/optional//boost_optional
|
||||
: windbg_lib_threaded ]
|
||||
[ run thread_safety_checking.cpp
|
||||
: : : <debug-symbols>on <library>.//test_impl_lib_windbg_cached $(LINKSHARED_WIND_CACHED)
|
||||
<library>/boost/optional//boost_optional
|
||||
: windbg_cached_lib_threaded ]
|
||||
[ run thread_safety_checking.cpp
|
||||
: : : <debug-symbols>on <library>.//test_impl_lib_basic $(LINKSHARED_BASIC)
|
||||
<library>/boost/optional//boost_optional
|
||||
: basic_lib_threaded ]
|
||||
|
||||
##### Tests with disabled debug symbols #####
|
||||
@@ -158,6 +166,7 @@ test-suite stacktrace_tests
|
||||
[ run thread_safety_checking.cpp
|
||||
: : : <debug-symbols>off
|
||||
<library>.//test_impl_lib_backtrace_no_dbg
|
||||
<library>/boost/optional//boost_optional
|
||||
$(LINKSHARED_BT)
|
||||
: backtrace_lib_no_dbg_threaded ]
|
||||
[ run thread_safety_checking.cpp
|
||||
@@ -179,36 +188,52 @@ test-suite stacktrace_tests
|
||||
[ run test_void_ptr_cast.cpp ]
|
||||
[ run test_num_conv.cpp ]
|
||||
|
||||
[ run test_from_exception_none.cpp : : : $(LINKSHARED_NOOP) <debug-symbols>on : from_exception_none_noop ]
|
||||
[ run test_from_exception_none.cpp : : : <define>BOOST_STACKTRACE_USE_NOOP $(NOOP_DEPS) <debug-symbols>on : from_exception_none_noop_ho ]
|
||||
[ run test_from_exception_none.cpp : : : $(LINKSHARED_BASIC) <debug-symbols>on : from_exception_none_basic ]
|
||||
[ run test_from_exception_none.cpp : : : $(FORCE_SYMBOL_EXPORT) $(BASIC_DEPS) <debug-symbols>on : from_exception_none_basic_ho ]
|
||||
[ run test_from_exception_none.cpp : : : $(LINKSHARED_BT) <debug-symbols>on : from_exception_none_bt ]
|
||||
[ run test_from_exception_none.cpp : : : <define>BOOST_STACKTRACE_USE_BACKTRACE $(BT_DEPS) <debug-symbols>on : from_exception_none_bt_ho ]
|
||||
[ run test_from_exception_none.cpp : : : $(LINKSHARED_WIND) <debug-symbols>on : from_exception_none_windbg ]
|
||||
[ run test_from_exception_none.cpp : : : <define>BOOST_STACKTRACE_USE_WINDBG $(WIND_DEPS) <debug-symbols>on : from_exception_none_windbg_ho ]
|
||||
[ run test_from_exception_none.cpp : : : $(LINKSHARED_WIND_CACHED) <debug-symbols>on : from_exception_none_windbg_cached ]
|
||||
[ run test_from_exception_none.cpp : : : <define>BOOST_STACKTRACE_USE_WINDBG_CACHED $(WICA_DEPS) <debug-symbols>on : from_exception_none_windbg_cached_ho ]
|
||||
|
||||
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_NOOP) <debug-symbols>on : from_exception_disabled_none ]
|
||||
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception <define>BOOST_STACKTRACE_USE_NOOP $(NOOP_DEPS) : from_exception_disabled_none_ho ]
|
||||
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_BASIC) <debug-symbols>on : from_exception_disabled_basic ]
|
||||
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(FORCE_SYMBOL_EXPORT) $(BASIC_DEPS) <debug-symbols>on : from_exception_disabled_basic_ho ]
|
||||
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_BT) <debug-symbols>on : from_exception_disabled_bt ]
|
||||
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception <define>BOOST_STACKTRACE_USE_BACKTRACE $(BT_DEPS) : from_exception_disabled_bt_ho ]
|
||||
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_WIND) <debug-symbols>on : from_exception_disabled_windbg ]
|
||||
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception <define>BOOST_STACKTRACE_USE_WINDBG $(WIND_DEPS) <debug-symbols>on : from_exception_disabled_windbg_ho ]
|
||||
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_WIND_CACHED) <debug-symbols>on : from_exception_disabled_windbg_cached ]
|
||||
[ run test_from_exception_none.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception <define>BOOST_STACKTRACE_USE_WINDBG_CACHED $(WICA_DEPS) <debug-symbols>on : from_exception_disabled_windbg_cached_ho ]
|
||||
|
||||
[ link test_from_exception.cpp : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_BASIC) <debug-symbols>on : from_exception_basic ]
|
||||
[ run test_from_exception.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_BT) <debug-symbols>on : from_exception_bt ]
|
||||
[ run test_from_exception.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_WIND) <debug-symbols>on : from_exception_windbg ]
|
||||
[ run test_from_exception.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception $(LINKSHARED_WIND_CACHED) <debug-symbols>on : from_exception_windbg_cached ]
|
||||
|
||||
[ link test_from_exception.cpp : <library>/boost/stacktrace//boost_stacktrace_from_exception $(FORCE_SYMBOL_EXPORT) $(BASIC_DEPS) <debug-symbols>on : from_exception_basic_ho ]
|
||||
[ run test_from_exception.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception <define>BOOST_STACKTRACE_USE_BACKTRACE $(BT_DEPS) <debug-symbols>on : from_exception_bt_ho ]
|
||||
[ run test_from_exception.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception <define>BOOST_STACKTRACE_USE_WINDBG $(WIND_DEPS) <debug-symbols>on : from_exception_windbg_ho ]
|
||||
[ run test_from_exception.cpp : : : <library>/boost/stacktrace//boost_stacktrace_from_exception <define>BOOST_STACKTRACE_USE_WINDBG_CACHED $(WICA_DEPS) <debug-symbols>on : from_exception_windbg_cached_ho ]
|
||||
;
|
||||
|
||||
# Assuring that examples compile and run. Adding sources from `examples` directory to the `type_index` test suite.
|
||||
for local p in [ glob ../example/*.cpp ]
|
||||
{
|
||||
local target_name = $(p[1]:B) ;
|
||||
local additional_dependency = ;
|
||||
local additional_dependency = <library>/boost/array//boost_array ;
|
||||
if $(target_name) = "terminate_handler"
|
||||
{
|
||||
additional_dependency = <library>/boost/filesystem//boost_filesystem <library>/boost/system//boost_system <target-os>linux:<library>rt ;
|
||||
additional_dependency += <library>/boost/filesystem//boost_filesystem <library>/boost/system//boost_system <target-os>linux:<library>rt ;
|
||||
}
|
||||
|
||||
if $(target_name) = "throwing_st"
|
||||
{
|
||||
additional_dependency = [ requires rtti ] ;
|
||||
additional_dependency += [ requires rtti ] <library>/boost/exception//boost_exception ;
|
||||
}
|
||||
|
||||
stacktrace_tests += [ run $(p) : : : <debug-symbols>on $(LINKSHARED_BT) $(additional_dependency) : backtrace_$(p2[1]:B) ] ;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# subject to 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)
|
||||
#
|
||||
# Copyright Antony Polukhin, 2016-2024.
|
||||
# Copyright Antony Polukhin, 2016-2025.
|
||||
|
||||
#
|
||||
# See https://svn.boost.org/trac/boost/wiki/TravisCoverals for description of this file
|
||||
@@ -21,7 +21,7 @@ init:
|
||||
# From this point and below code is same for all the Boost libs
|
||||
###############################################################################################################
|
||||
|
||||
version: 1.84.{build}-{branch}
|
||||
version: 1.88.{build}-{branch}
|
||||
|
||||
# branches to build
|
||||
branches:
|
||||
@@ -63,13 +63,10 @@ before_build:
|
||||
- git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git %BOOST%
|
||||
- cd %BOOST%
|
||||
- git submodule update --init --depth 10 tools/build tools/boostdep
|
||||
libs/filesystem libs/atomic libs/system libs/interprocess libs/array
|
||||
libs/iterator libs/detail libs/exception libs/smart_ptr libs/mpl
|
||||
libs/align libs/container libs/tuple libs/intrusive libs/scope
|
||||
|
||||
- rm -rf %BOOST%/libs/%BOOST_LIBS_FOLDER%
|
||||
- mv -f %APPVEYOR_BUILD_FOLDER% %BOOST%/libs/%BOOST_LIBS_FOLDER%
|
||||
- python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 2" %BOOST_LIBS_FOLDER%
|
||||
- python tools/boostdep/depinst/depinst.py --include example --git_args "--depth 10 --jobs 2" %BOOST_LIBS_FOLDER%
|
||||
|
||||
build_script:
|
||||
- cmd /c bootstrap
|
||||
|
||||
15
test/cmake_install_test/CMakeLists.txt
Normal file
15
test/cmake_install_test/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright 2018-2021 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.20)
|
||||
|
||||
project(cmake_install_test LANGUAGES CXX)
|
||||
|
||||
find_package(boost_stacktrace REQUIRED)
|
||||
|
||||
add_executable(main main.cpp)
|
||||
target_link_libraries(main Boost::stacktrace)
|
||||
|
||||
enable_testing()
|
||||
add_test(main main)
|
||||
12
test/cmake_install_test/main.cpp
Normal file
12
test/cmake_install_test/main.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
// Copyright 2022-2025 Antony Polukhin
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/stacktrace/stacktrace.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << boost::stacktrace::stacktrace() << std::endl;
|
||||
}
|
||||
46
test/cmake_subdir_test/CMakeLists.txt
Normal file
46
test/cmake_subdir_test/CMakeLists.txt
Normal file
@@ -0,0 +1,46 @@
|
||||
# Copyright 2018-2021 Peter Dimov
|
||||
# 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
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.20)
|
||||
|
||||
project(cmake_subdir_test LANGUAGES CXX)
|
||||
|
||||
# Put boost_stacktrace_*.dll in the same directory as main.exe
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
add_subdirectory(../.. boostorg/stacktrace)
|
||||
|
||||
# boostdep --brief stacktrace
|
||||
|
||||
set(deps
|
||||
|
||||
# Primary dependencies
|
||||
|
||||
assert
|
||||
config
|
||||
container_hash
|
||||
core
|
||||
predef
|
||||
winapi
|
||||
|
||||
# Secondary dependencies
|
||||
|
||||
describe
|
||||
mp11
|
||||
static_assert
|
||||
throw_exception
|
||||
|
||||
)
|
||||
|
||||
foreach(dep IN LISTS deps)
|
||||
|
||||
add_subdirectory(../../../${dep} boostorg/${dep})
|
||||
|
||||
endforeach()
|
||||
|
||||
add_executable(main main.cpp)
|
||||
target_link_libraries(main Boost::stacktrace)
|
||||
|
||||
enable_testing()
|
||||
add_test(main main)
|
||||
12
test/cmake_subdir_test/main.cpp
Normal file
12
test/cmake_subdir_test/main.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2019 Peter Dimov
|
||||
// Copyright 2022-2025 Antony Polukhin
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/stacktrace/stacktrace.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << boost::stacktrace::stacktrace() << std::endl;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <boost/stacktrace.hpp>
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <cctype>
|
||||
@@ -257,7 +258,57 @@ void test_empty_basic_stacktrace() {
|
||||
BOOST_TEST(!(st > st_t(0, 0)));
|
||||
}
|
||||
|
||||
int main() {
|
||||
void test_stacktrace_limits()
|
||||
{
|
||||
BOOST_TEST_EQ(boost::stacktrace::stacktrace(0, 1).size(), 1);
|
||||
BOOST_TEST_EQ(boost::stacktrace::stacktrace(1, 1).size(), 1);
|
||||
}
|
||||
|
||||
std::size_t get_file_size(const char* file_name) {
|
||||
std::ifstream file(file_name, std::ios::binary | std::ios::ate);
|
||||
const auto file_size = file.tellg();
|
||||
BOOST_TEST(file_size > 0);
|
||||
return static_cast<std::size_t>(file_size);
|
||||
}
|
||||
|
||||
uintptr_t get_address_from_frame(const std::string& frame) {
|
||||
std::size_t address = 0;
|
||||
std::string hex_address;
|
||||
std::size_t pos = frame.find("0x");
|
||||
|
||||
if (pos != std::string::npos) {
|
||||
// Extract the hex address substring
|
||||
hex_address = frame.substr(pos + 2); // Skip "0x"
|
||||
|
||||
// Convert hex string to std::size_t
|
||||
std::stringstream ss;
|
||||
ss << std::hex << hex_address;
|
||||
ss >> address;
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
void test_relative_virtual_address(const char* file_path)
|
||||
{
|
||||
const auto frame = to_string(boost::stacktrace::stacktrace(0, 1).as_vector().front());
|
||||
|
||||
// Skip the test if the frame does not contain an address
|
||||
if (frame.find("0x") == std::string::npos) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto file_size = get_file_size(file_path);
|
||||
BOOST_TEST(file_size > 0);
|
||||
|
||||
const auto address = get_address_from_frame(frame);
|
||||
BOOST_TEST(address > 0);
|
||||
|
||||
// Verify that the address is within the binary
|
||||
BOOST_TEST(address <= file_size);
|
||||
}
|
||||
|
||||
int main(const int, const char* argv[]) {
|
||||
test_deeply_nested_namespaces();
|
||||
test_frames_string_data_validity();
|
||||
test_nested<15>();
|
||||
@@ -275,8 +326,9 @@ int main() {
|
||||
test_comparisons_base(make_some_stacktrace1(), make_some_stacktrace2());
|
||||
|
||||
test_nested<260>(false);
|
||||
BOOST_TEST(boost::stacktrace::stacktrace(0, 1).size() == 1);
|
||||
BOOST_TEST(boost::stacktrace::stacktrace(1, 1).size() == 1);
|
||||
|
||||
test_stacktrace_limits();
|
||||
test_relative_virtual_address(argv[0]);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2023-2024.
|
||||
// Copyright Antony Polukhin, 2023-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -31,7 +31,27 @@ BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void in_test_throw_1(const char* msg) {
|
||||
|
||||
BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void in_test_throw_2(const char* msg) {
|
||||
std::string new_msg{msg};
|
||||
throw std::runtime_error(new_msg);
|
||||
throw std::logic_error(new_msg);
|
||||
}
|
||||
|
||||
BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void in_test_rethrow_1(const char* msg) {
|
||||
try {
|
||||
in_test_throw_1(msg);
|
||||
} catch (const std::exception&) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void in_test_rethrow_2(const char* msg) {
|
||||
try {
|
||||
in_test_throw_2(msg);
|
||||
} catch (const std::exception&) {
|
||||
try {
|
||||
in_test_throw_1(msg);
|
||||
} catch (const std::exception&) {}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void test_no_exception() {
|
||||
@@ -67,6 +87,31 @@ BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void test_after_other_exception() {
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void test_rethrow() {
|
||||
try {
|
||||
in_test_rethrow_1("test rethrow");
|
||||
} catch (const std::exception&) {
|
||||
auto trace = stacktrace::from_current_exception();
|
||||
BOOST_TEST(trace);
|
||||
std::cout << "Tarce in test_rethrow(): " << trace << '\n';
|
||||
BOOST_TEST(to_string(trace).find("in_test_throw_1") != std::string::npos);
|
||||
BOOST_TEST(to_string(trace).find("in_test_rethrow_1") != std::string::npos);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void test_rethrow_after_other_exception() {
|
||||
try {
|
||||
in_test_rethrow_2("test_rethrow_after_other_exception");
|
||||
} catch (const std::exception&) {
|
||||
auto trace = stacktrace::from_current_exception();
|
||||
BOOST_TEST(trace);
|
||||
std::cout << "Tarce in test_rethrow_after_other_exception(): " << trace << '\n';
|
||||
BOOST_TEST(to_string(trace).find("in_test_throw_1") == std::string::npos);
|
||||
BOOST_TEST(to_string(trace).find("in_test_throw_2") != std::string::npos);
|
||||
BOOST_TEST(to_string(trace).find("in_test_rethrow_2") != std::string::npos);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void test_nested() {
|
||||
try {
|
||||
in_test_throw_1("test_other_exception_active");
|
||||
@@ -103,7 +148,11 @@ BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void test_rethrow_nested() {
|
||||
BOOST_TEST(trace);
|
||||
std::cout << "Tarce in test_rethrow_nested(): " << trace << '\n';
|
||||
BOOST_TEST(to_string(trace).find("in_test_throw_1") == std::string::npos);
|
||||
#if defined(BOOST_MSVC)
|
||||
BOOST_TEST(to_string(trace).find("in_test_throw_2") == std::string::npos);
|
||||
#else
|
||||
BOOST_TEST(to_string(trace).find("in_test_throw_2") != std::string::npos);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +182,11 @@ BOOST_NOINLINE BOOST_SYMBOL_VISIBLE void test_from_other_thread() {
|
||||
BOOST_TEST(trace);
|
||||
std::cout << "Tarce in test_rethrow_nested(): " << trace << '\n';
|
||||
BOOST_TEST(to_string(trace).find("in_test_throw_1") == std::string::npos);
|
||||
#if defined(BOOST_MSVC)
|
||||
BOOST_TEST(to_string(trace).find("in_test_throw_2") == std::string::npos);
|
||||
#else
|
||||
BOOST_TEST(to_string(trace).find("in_test_throw_2") != std::string::npos);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -146,6 +199,8 @@ int main() {
|
||||
test_no_exception();
|
||||
test_trace_from_exception();
|
||||
test_after_other_exception();
|
||||
test_rethrow();
|
||||
test_rethrow_after_other_exception();
|
||||
test_nested();
|
||||
test_rethrow_nested();
|
||||
test_from_other_thread();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2023-2024.
|
||||
// Copyright Antony Polukhin, 2023-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2022-2024.
|
||||
// Copyright Antony Polukhin, 2022-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright Antony Polukhin, 2016-2024.
|
||||
// Copyright Antony Polukhin, 2016-2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
Reference in New Issue
Block a user