Compare commits

...

94 Commits

Author SHA1 Message Date
Antony Polukhin
c6e7712868 update CI (1) 2023-05-21 12:42:28 +03:00
Antony Polukhin
c836328054 update CI setup 2023-05-21 10:45:29 +03:00
Antony Polukhin
71da3cfd56 add C++03 deprecation warnings 2023-05-14 20:06:38 +03:00
Antony Polukhin
95065ca638 Merge pull request #132 from Chocobo1/typo
Fix typos
2023-02-21 14:27:08 +03:00
Chocobo1
b9a0a12f1c Fix typo 2023-02-08 17:45:10 +08:00
Antony Polukhin
4cf47389c1 Update copyright years 2023-01-19 10:21:22 +03:00
Antony Polukhin
d904d26f4f Fix multithreading flag detection for backtrace_create_state if BOOST_STACKTRACE_BACKTRACE_FORCE_STATIC is defined 2023-01-18 17:16:51 +03:00
Antony Polukhin
cd4c5fe554 fix a type that was noted in https://github.com/boostorg/stacktrace/issues/118#issuecomment-1315142952 2023-01-18 17:14:49 +03:00
Antony Polukhin
12e3743e58 Simplify Jamfile a little-bit
Relates: https://github.com/boostorg/stacktrace/issues/119
2022-09-12 16:29:05 +03:00
Antony Polukhin
6db6fd0c01 Use BOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE while detecting the libbacktrace availability in b2
Fixes: https://github.com/boostorg/stacktrace/issues/115
2022-09-12 15:46:46 +03:00
Antony Polukhin
57db1f511e Update CI 2022-09-02 17:40:44 +03:00
Antony Polukhin
308b7f6b08 allow forcing the static backtrace_state
References: https://github.com/boostorg/stacktrace/issues/118
2022-09-02 12:20:30 +03:00
Antony Polukhin
b856a99f9f fix and make sure that boost/stacktrace/stacktrace.hpp header has no unresolved references
Fixes: https://github.com/boostorg/stacktrace/issues/116
2022-09-02 10:38:17 +03:00
Antony Polukhin
6bf1a98d97 Merge pull request #127 from boostorg/antoshkka/no-more-strlen
avoid strlen() calls by using the size-1 from GetNameByOffset
2022-09-01 19:45:36 +03:00
Antony Polukhin
cc4d16e2ad avoid strlen() calls by using the size-1 from GetNameByOffset
Refs: https://github.com/boostorg/stacktrace/issues/122
2022-09-01 19:02:46 +03:00
Antony Polukhin
7c6778e9f4 Merge pull request #126 from boostorg/antoshkka/no-more-com-init
remove COM-initialization related tests and notes in docs
2022-09-01 18:51:16 +03:00
Antony Polukhin
e5940e7103 remove COM-initialization related tests and notes in docs 2022-09-01 17:51:22 +03:00
Antony Polukhin
bac3611ad8 Merge pull request #123 from AlexGuteniev/windows-dbgeng-tweak
Don't initialize COM, as it is not required
2022-09-01 17:42:13 +03:00
Alex Guteniev
9e8510076d BOOST_STACKTRACE_USE_WINDBG_CACHED support 2022-02-18 20:08:31 +02:00
Alex Guteniev
a60ee55b36 Don't initialize COM
Resolve #121
2022-02-18 19:45:26 +02:00
Antony Polukhin
75b7986f97 update copyright years 2022-01-30 14:47:24 +03:00
Antony Polukhin
3f3f9020fb do not use depth 1 for checkouts in CI 2021-09-20 21:55:43 +03:00
Antony Polukhin
898fedac41 modernize CI setup 2021-09-11 18:15:38 +03:00
Peter Dimov
79aff77771 Fix checks and build to work on Cygwin 2021-06-01 04:26:35 +03:00
Peter Dimov
1be59df18e Do not use find_package(Backtrace) 2021-06-01 03:39:23 +03:00
Peter Dimov
1dae3faf43 Check for backtrace both with Backtrace_HEADER and without it (it's set to execinfo.h on Linux and doesn't work, whereas backtrace.h does) 2021-06-01 02:59:06 +03:00
Peter Dimov
99b7015508 Define BOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE 2021-06-01 01:56:34 +03:00
Peter Dimov
18012f81da Fix spelling of Backtrace_FOUND 2021-06-01 01:38:58 +03:00
Peter Dimov
76f902f366 Add CMakeLists.txt 2021-05-31 23:04:04 +03:00
Antony Polukhin
b37e0d8e9f use HTTPS links in Readme 2021-04-27 11:19:55 +03:00
Antony Polukhin
9a114f8256 update links in Readme, add badges, run coverage reports only from GithubActions 2021-04-24 21:46:32 +03:00
Antony Polukhin
b75a37dc48 do not run on MacOs in GithubActions CI 2021-04-24 20:25:35 +03:00
Antony Polukhin
1631213c0c update CI: fixes 2021-04-24 11:18:22 +03:00
Antony Polukhin
cadf1bc311 update CI: add depinst.py dirs 2021-04-24 10:38:35 +03:00
Antony Polukhin
26f66b58e9 update CIs 2021-04-23 20:38:10 +03:00
Antony Polukhin
7b19672b67 fix broken link 2021-04-23 20:29:34 +03:00
Antony Polukhin
67cc2e9017 Merge pull request #107 from sdarwin/githubactions
GitHub Actions config
2021-04-18 14:10:00 +03:00
sdarwin
4b4472cccb Add GitHub Actions config [ci skip] 2021-03-05 16:25:14 +00:00
Antony Polukhin
08d720adbd attempt to fix coverage reports 2021-01-04 19:08:40 +03:00
Antony Polukhin
a00587f4d7 update copyright years 2021-01-03 19:24:15 +03:00
Antony Polukhin
9c462940b1 Merge pull request #104 from sdarwin/lcov
update lcov in .travis.yml
2021-01-03 12:51:27 +03:00
sdarwin
7fdaebb8ef update lcov in .travis.yml 2020-12-30 15:51:38 +00:00
Antony Polukhin
15f6b30f12 Better support for pre-C++11 builds on clang (fixes #102) 2020-12-19 14:35:28 +03:00
Antony Polukhin
4a8b14b2d7 disable test on Windows 2020-12-18 11:04:34 +03:00
Antony Polukhin
e4576bfae2 attempt to deal with hangs on some platforms 2020-12-16 12:09:01 +03:00
Antony Polukhin
7985a04380 bigger warning for signal handlers (fixes #71) 2020-12-15 17:00:34 +03:00
Antony Polukhin
d84457e2a0 update meta info on stacktrace 2020-12-15 16:51:07 +03:00
Antony Polukhin
66aba44f79 do not recommend safe_dump_to (fixes #98) 2020-12-15 16:48:29 +03:00
Antony Polukhin
e75d2ff93b Merge pull request #91 from jeremiahar/develop
Add support for disabled exceptions
2020-05-28 16:48:43 +03:00
Jeremiah Rodriguez
a8a4cefb52 Add support for disabled exceptions 2020-05-26 13:28:32 -07:00
Antony Polukhin
f931528c87 CI fixes 2020-04-06 18:47:50 +03:00
Antony Polukhin
9b5bc54fe3 provide documentation on distribution of PDBs (fixes #55, #47) 2020-01-23 23:56:01 +03:00
Antony Polukhin
178d2875d7 Remove ugly things from the test (refs #86) 2020-01-21 09:14:40 +03:00
Antony Polukhin
ade7d54dc7 update copyright year 2020-01-18 14:11:02 +03:00
Antony Polukhin
211d291253 Merge pull request #84 from doj/develop
fix typo in stacktrace.qbk
2019-11-17 09:13:49 +03:00
Antony Polukhin
b72cc6cdfd Adjust coverage reports in CI (3) 2019-11-16 17:28:44 +03:00
Antony Polukhin
99e07cbea6 Adjust coverage reports in CI (2) 2019-11-16 13:11:08 +03:00
Antony Polukhin
922305ea7d Adjust CI coverage reports 2019-11-16 12:44:01 +03:00
Antony Polukhin
2fce6957d6 More CI workarounds 2019-11-16 10:51:49 +03:00
Antony Polukhin
2cfcbf4247 Update Jamfile.v2 2019-11-15 19:07:10 +03:00
Dirk Jagdmann
0bddb90c1d fix typo in stacktrace.qbk 2019-11-14 13:29:33 -08:00
Antony Polukhin
b6bc847b0c Fine tune inspect tool 2019-11-12 20:02:46 +03:00
Antony Polukhin
6c5b7e51d5 Install binutils 2019-11-12 19:28:48 +03:00
Antony Polukhin
acf5b12d02 Replace tabs with spaces 2019-11-12 10:16:57 +03:00
Antony Polukhin
9c3bdd4d0e Update .travis.yml 2019-11-12 10:14:53 +03:00
Antony Polukhin
dc0f0c752b CI fixes 2019-11-12 09:51:14 +03:00
Antony Polukhin
09255fc94b Update .travis.yml 2019-11-11 19:21:10 +03:00
Antony Polukhin
293e1f43f6 Typo fix 2019-07-26 19:01:10 +03:00
Antony Polukhin
7379a5cc08 Fix msvc-9 build 2019-07-26 17:12:52 +03:00
Antony Polukhin
7c7271d9bc CI coverage fixes (5) 2019-06-30 15:26:11 +03:00
Antony Polukhin
6007c216b9 CI coverage fixes (4) 2019-06-30 13:16:12 +03:00
Antony Polukhin
d5bbf7853a CI coverage fixes (3) 2019-06-30 12:30:30 +03:00
Antony Polukhin
0be61ab0b8 CI coverage fix (2) 2019-06-30 10:14:44 +03:00
Antony Polukhin
43b837d181 Attempt to fix coverage 2019-06-29 20:43:33 +03:00
Antony Polukhin
2f75119cd0 Use lcov 1.14 2019-06-29 11:40:10 +03:00
Antony Polukhin
36734b1531 Trim null characters on Windows (fixes #78) 2019-06-29 10:44:27 +03:00
Antony Polukhin
2d810e294f Try to reproduce the error from #78 in tests 2019-06-28 22:38:49 +03:00
Antony Polukhin
6e79da7420 Fix frame info output with TSAN 2019-06-28 11:12:35 +03:00
Antony Polukhin
71acd94944 Fix empty frame info output with TSAN 2019-06-28 10:41:44 +03:00
Antony Polukhin
324a303fb0 Better diagnostics for test 2019-06-27 13:17:08 +03:00
Antony Polukhin
876349f0d6 Use gold linker for TSAN 2019-06-27 10:38:37 +03:00
Antony Polukhin
63d5d2730f Fix CI runs with thread sanitizer 2019-06-26 18:11:26 +03:00
Antony Polukhin
248eedd52f Fix ubsan library version 2019-06-26 14:50:20 +03:00
Antony Polukhin
c906a69c1d Test on GCC-8 because of tsan issues in GCC-6 2019-06-26 13:46:45 +03:00
Antony Polukhin
4f9da2ae71 Manually force rebuild for thread sanitizer tests 2019-06-26 13:12:34 +03:00
Antony Polukhin
1ad62e582a Add comment about async signal safety for PR #70 2019-01-12 22:37:31 +03:00
Antony Polukhin
5c6740b680 Merge branch 'develop' of github.com:boostorg/stacktrace into develop 2019-01-12 22:15:24 +03:00
Antony Polukhin
d9d6512743 Update copyright years 2019-01-12 22:15:16 +03:00
Antony Polukhin
158a59ae51 Merge pull request #70 from ivanarh/use_execinfo_backtrace
Added an option to use libc backtrace function from execinfo.h
2019-01-11 21:59:44 +03:00
Antony Polukhin
839a1a127d Update collect_unwind.ipp 2019-01-11 13:27:43 +03:00
Ivan Ponomarev
411d92cbf3 Forced backtrace() function usage on iOS, 32-bit ARM architecture. Used macros from Boost predef. 2019-01-09 23:07:37 +03:00
Ivan Ponomarev
1b7956a40d Added an ability to use libc backtrace() function (from execinfo.h) instead of _Unwind_Backtrace on Unix-like systems. Useful on iOS 32-bit ARM where _Unwind_Backtrace symbol is undefined. 2019-01-09 01:04:47 +03:00
Antony Polukhin
d708d17ecd Suppress warning (fixes #69) 2019-01-05 13:48:53 +03:00
Antony Polukhin
d946b124ba Fix typo noted by Telegram user PRoSToC0der 2018-12-13 11:00:33 +03:00
60 changed files with 641 additions and 375 deletions

168
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,168 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-12
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
linkflags: "linkflags=--coverage -lasan -lubsan"
gcov_tool: "gcov-12"
launcher: "testing.launcher=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.8"
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
# TODO: fix and uncomment
#- toolset: clang
# cxxstd: "03,11,14,17,2a"
# os: macos-10.15
# cxxflags: "cxxflags=-fsanitize=address,undefined -fno-sanitize-recover=undefined -D_GNU_SOURCE=1"
# linkflags: "linkflags=-fsanitize=address,undefined"
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt 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 10 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init --depth 10 --jobs 2 tools/boostdep tools/inspect libs/filesystem
python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 3" filesystem
rm -rf libs/$LIBRARY/*
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--depth 10 --jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
./b2 -j4 variant=debug tools/inspect/build
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release "${{matrix.cxxflags}}" "${{matrix.linkflags}}" "${{matrix.launcher}}"
dist/bin/inspect libs/$LIBRARY
- name: Prepare coverage data
if: matrix.gcov_tool
run: |
mkdir -p $GITHUB_WORKSPACE/coveralls
echo -e "#!/bin/bash\nexec ${{matrix.gcov_tool}} \"\$@\"" > $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
chmod +x $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
wget https://github.com/linux-test-project/lcov/archive/v1.16.zip
unzip v1.16.zip
LCOV="`pwd`/lcov-1.16/bin/lcov --gcov-tool $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh"
echo "$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory `pwd`/libs/$LIBRARY/test --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info"
$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory ../boost-root/ --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info
$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info "/usr*" "*/$LIBRARY/test/*" ${{matrix.ignore_coverage}} "*/$LIBRARY/tests/*" "*/$LIBRARY/examples/*" "*/$LIBRARY/example/*" -o $GITHUB_WORKSPACE/coveralls/coverage.info
cd ../boost-root
OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$LIBRARY\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
echo $OTHER_LIBS
eval "$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info $OTHER_LIBS -o $GITHUB_WORKSPACE/coveralls/coverage.info"
- name: Coveralls
uses: coverallsapp/github-action@master
if: matrix.gcov_tool
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./coveralls/coverage.info
parallel: true
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc
cxxstd: "14,17,latest"
addrmd: 64
os: windows-2022
- toolset: msvc-14.2
cxxstd: "14,17,latest"
addrmd: 64
os: windows-2019
#- toolset: gcc
# cxxstd: "03,11,14,17,2a"
# addrmd: 64
# os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- 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 10 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 --include benchmark --include example --include examples --include tools --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
finish:
needs: posix
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.github_token }}
parallel-finished: true

View File

@@ -1,123 +0,0 @@
# 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)
#
# Copyright Antony Polukhin 2014-2018.
#
# See https://svn.boost.org/trac/boost/wiki/TravisCoverals for description of this file
# and how it can be used with Boost libraries.
#
# File revision #7
sudo: false
language: cpp
compiler:
- gcc
# - clang
os:
- linux
env:
global:
# Autodetect Boost branch by using the following code: - BRANCH_TO_TEST=$TRAVIS_BRANCH
# or just directly specify it
#- BRANCH_TO_TEST=$TRAVIS_BRANCH
- BRANCH_TO_TEST=develop
# Files, which coverage results must be ignored (files from other projects).
# Example: - IGNORE_COVERAGE='*/boost/progress.hpp */filesystem/src/*'
- IGNORE_COVERAGE='*/numeric/conversion/converter_policies.hpp */boost/progress.hpp */filesystem/src/* */libs/timer/src/* */thread/src/* */pthread/once_atomic.cpp */src/pthread/thread.cpp */thread/src/future.cpp */boost/operators.hpp'
# Explicitly remove the following library from Boost. This may be usefull, if you're for example running Travis
# from `Boost.DLL` repo, while Boost already has `dll`.
#
# By default is eaual to - BOOST_REMOVE=$(basename $TRAVIS_BUILD_DIR)
# This will force to use local repo content, instead of the Boost's default.
- BOOST_REMOVE=$(basename $TRAVIS_BUILD_DIR)
matrix:
# Note that "--coverage -fsanitize=address,leak,undefined -DBOOST_TRAVISCI_BUILD" are added automatically lower in code
- CXX_FLAGS="-std=c++98" LINK_FLAGS="" TOOLSET=gcc-6
- CXX_FLAGS="-std=c++11" LINK_FLAGS="" TOOLSET=gcc-6
- CXX_FLAGS="-std=c++1y" LINK_FLAGS="" TOOLSET=gcc-6
- CXX_FLAGS="-std=c++11 -O0" LINK_FLAGS="" TOOLSET=gcc-6
- CXX_FLAGS="-std=c++11 -O1" LINK_FLAGS="" TOOLSET=gcc-6
#- CXX_FLAGS="-std=c++11 -stdlib=libc++" LINK_FLAGS="-stdlib=libc++" TOOLSET=clang
#- CXX_FLAGS="-std=c++1y -stdlib=libc++" LINK_FLAGS="-stdlib=libc++" TOOLSET=clang
###############################################################################################################
# From this point and below code is same for all the Boost libs
###############################################################################################################
# Installing additional tools
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- git-core
packages:
- git
- python-yaml
- gcc-6
- g++-6
- clang
- libc++-dev
before_install:
# Set this to the name of the library
- PROJECT_TO_TEST=`basename $TRAVIS_BUILD_DIR`
# Cloning Boost libraries (fast nondeep cloning)
- BOOST=$HOME/boost-local
- echo "Testing $PROJECT_TO_TEST, to remove $BOOST/libs/$BOOST_REMOVE, testing branch $BRANCH_TO_TEST"
- git init $BOOST
- cd $BOOST
- git remote add --no-tags -t $BRANCH_TO_TEST origin https://github.com/boostorg/boost.git
- git fetch --depth=1
- git checkout $BRANCH_TO_TEST
- git submodule update --jobs=3 --init --merge
- git remote set-branches --add origin $BRANCH_TO_TEST
- git pull --recurse-submodules
- git status
- rm -rf $BOOST/libs/$BOOST_REMOVE
- mv $TRAVIS_BUILD_DIR $BOOST/libs/$PROJECT_TO_TEST
- TRAVIS_BUILD_DIR=$BOOST/libs/$PROJECT_TO_TEST
- ./bootstrap.sh
- ./b2 headers
- cd $BOOST/libs/$PROJECT_TO_TEST/test/
script:
# `--coverage` flags required to generate coverage info for Coveralls
- ../../../b2 -a "testing.launcher=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.3 " address-model=64 architecture=x86 toolset=$TOOLSET cxxflags="--coverage -fsanitize=address,undefined -DBOOST_TRAVISCI_BUILD $CXX_FLAGS" linkflags="$LINK_FLAGS --coverage -lasan -lubsan"
- ../../../b2 -a address-model=64 architecture=x86 toolset=$TOOLSET cxxflags="-fsanitize=thread -DBOOST_TRAVISCI_BUILD $CXX_FLAGS" linkflags="$LINK_FLAGS -ltsan"
after_success:
# Copying Coveralls data to a separate folder
- mkdir -p $TRAVIS_BUILD_DIR/coverals
- find ../../../bin.v2/ -name "*.gcda" -exec cp "{}" $TRAVIS_BUILD_DIR/coverals/ \;
- find ../../../bin.v2/ -name "*.gcno" -exec cp "{}" $TRAVIS_BUILD_DIR/coverals/ \;
- find ../../../bin.v2/ -name "*.da" -exec cp "{}" $TRAVIS_BUILD_DIR/coverals/ \;
- find ../../../bin.v2/ -name "*.no" -exec cp "{}" $TRAVIS_BUILD_DIR/coverals/ \;
- wget https://github.com/linux-test-project/lcov/archive/v1.12.zip
- unzip v1.12.zip
- LCOV="`pwd`/lcov-1.12/bin/lcov --gcov-tool gcov-6"
# Preparing Coveralls data by changind data format to a readable one
- echo "$LCOV --directory $TRAVIS_BUILD_DIR/coverals --base-directory `pwd` --capture --output-file $TRAVIS_BUILD_DIR/coverals/coverage.info"
- $LCOV --directory $TRAVIS_BUILD_DIR/coverals --base-directory `pwd` --capture --output-file $TRAVIS_BUILD_DIR/coverals/coverage.info
# ... erasing /test/ /example/ folder data
- cd $BOOST
- $LCOV --remove $TRAVIS_BUILD_DIR/coverals/coverage.info "/usr*" "*/$PROJECT_TO_TEST/test/*" $IGNORE_COVERAGE "*/$PROJECT_TO_TEST/tests/*" "*/$PROJECT_TO_TEST/examples/*" "*/$PROJECT_TO_TEST/example/*" -o $TRAVIS_BUILD_DIR/coverals/coverage.info
# ... erasing data that is not related to this project directly
- OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$PROJECT_TO_TEST\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
- echo $OTHER_LIBS
- eval "$LCOV --remove $TRAVIS_BUILD_DIR/coverals/coverage.info $OTHER_LIBS -o $TRAVIS_BUILD_DIR/coverals/coverage.info"
# Sending data to Coveralls
- cd $TRAVIS_BUILD_DIR
- gem install coveralls-lcov
- coveralls-lcov coverals/coverage.info

106
CMakeLists.txt Normal file
View File

@@ -0,0 +1,106 @@
# Copyright 2020, 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.16)
project(boost_stacktrace VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
function(stacktrace_add_library suffix opt libs defs)
if(NOT opt)
return()
endif()
add_library(boost_stacktrace_${suffix}
src/${suffix}.cpp
)
add_library(Boost::stacktrace_${suffix} ALIAS boost_stacktrace_${suffix})
target_include_directories(boost_stacktrace_${suffix} PUBLIC include)
target_link_libraries(boost_stacktrace_${suffix}
PUBLIC
Boost::array
Boost::config
Boost::container_hash
Boost::core
Boost::predef
Boost::static_assert
Boost::type_traits
Boost::winapi
PRIVATE
${libs}
)
target_compile_definitions(boost_stacktrace_${suffix}
PUBLIC BOOST_STACKTRACE_NO_LIB
PRIVATE BOOST_STACKTRACE_SOURCE ${defs}
)
if(BUILD_SHARED_LIBS)
target_compile_definitions(boost_stacktrace_${suffix} PUBLIC BOOST_STACKTRACE_DYN_LINK)
else()
target_compile_definitions(boost_stacktrace_${suffix} PUBLIC BOOST_STACKTRACE_STATIC_LINK)
endif()
if(BOOST_SUPERPROJECT_VERSION AND NOT CMAKE_VERSION VERSION_LESS 3.13)
boost_install(TARGETS boost_stacktrace_${suffix} VERSION ${BOOST_SUPERPROJECT_VERSION} HEADER_DIRECTORY include)
endif()
endfunction()
include(CheckCXXSourceCompiles)
function(stacktrace_check var source incs libs defs)
set(CMAKE_REQUIRED_INCLUDES "${incs}")
list(APPEND CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/build")
set(CMAKE_REQUIRED_LIBRARIES "${libs}")
set(CMAKE_REQUIRED_DEFINITIONS "${defs}")
check_cxx_source_compiles("#include \"${source}\"" ${var})
set(${var} ${${var}} PARENT_SCOPE)
endfunction()
stacktrace_check(BOOST_STACKTRACE_HAS_BACKTRACE has_backtrace.cpp "" "backtrace" "")
set(_default_addr2line ON)
if(WIN32 AND NOT CMAKE_CXX_PLATFORM_ID MATCHES "Cygwin")
set(_default_addr2line OFF)
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" "")
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})
unset(_default_addr2line)
message(STATUS "Boost.Stacktrace: "
"noop ${BOOST_STACKTRACE_ENABLE_NOOP}, "
"backtrace ${BOOST_STACKTRACE_ENABLE_BACKTRACE}, "
"addr2line ${BOOST_STACKTRACE_ENABLE_ADDR2LINE}, "
"basic ${BOOST_STACKTRACE_ENABLE_BASIC}, "
"windbg ${BOOST_STACKTRACE_ENABLE_WINDBG}, "
"windbg_cached ${BOOST_STACKTRACE_ENABLE_WINDBG_CACHED}"
)
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(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")
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()

View File

@@ -1,15 +1,17 @@
### Stacktrace
# [Boost.Stacktrace](https://boost.org/libs/stacktrace)
Library for storing and printing backtraces.
[Documentation and examples.](http://boostorg.github.io/stacktrace/index.html)
Boost.Stacktrace is a part of the [Boost C++ Libraries](https://github.com/boostorg).
### Test results
@ | Build | Tests coverage | More info
----------------|-------------- | -------------- |-----------
Develop branch: | [![Build Status](https://travis-ci.org/boostorg/stacktrace.svg?branch=develop)](https://travis-ci.org/boostorg/stacktrace) [![Build status](https://ci.appveyor.com/api/projects/status/l3aak4j8k39rx08t/branch/develop?svg=true)](https://ci.appveyor.com/project/apolukhin/stacktrace/branch/develop) | [![Coverage Status](https://coveralls.io/repos/github/boostorg/stacktrace/badge.svg?branch=develop)](https://coveralls.io/github/boostorg/stacktrace?branch=develop) | [details...](http://www.boost.org/development/tests/develop/developer/stacktrace.html)
Master branch: | [![Build Status](https://travis-ci.org/boostorg/stacktrace.svg?branch=master)](https://travis-ci.org/boostorg/stacktrace) [![Build status](https://ci.appveyor.com/api/projects/status/l3aak4j8k39rx08t/branch/master?svg=true)](https://ci.appveyor.com/project/apolukhin/stacktrace/branch/master) | [![Coverage Status](https://coveralls.io/repos/github/boostorg/stacktrace/badge.svg?branch=master)](https://coveralls.io/github/boostorg/stacktrace?branch=master) | [details...](http://www.boost.org/development/tests/master/developer/stacktrace.html)
Develop branch: | [![CI](https://github.com/boostorg/stacktrace/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/stacktrace/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/l3aak4j8k39rx08t/branch/develop?svg=true)](https://ci.appveyor.com/project/apolukhin/stacktrace/branch/develop) | [![Coverage Status](https://coveralls.io/repos/github/boostorg/stacktrace/badge.svg?branch=develop)](https://coveralls.io/github/boostorg/stacktrace?branch=develop) | [details...](https://www.boost.org/development/tests/develop/developer/stacktrace.html)
Master branch: | [![CI](https://github.com/boostorg/stacktrace/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/stacktrace/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/l3aak4j8k39rx08t/branch/master?svg=true)](https://ci.appveyor.com/project/apolukhin/stacktrace/branch/master) | [![Coverage Status](https://coveralls.io/repos/github/boostorg/stacktrace/badge.svg?branch=master)](https://coveralls.io/github/boostorg/stacktrace?branch=master) | [details...](https://www.boost.org/development/tests/master/developer/stacktrace.html)
[Latest developer documentation](https://www.boost.org/doc/libs/develop/doc/html/stacktrace.html)
### License
Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
Distributed under the [Boost Software License, Version 1.0](https://boost.org/LICENSE_1_0.txt).

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2016-2018, Antony Polukhin.
# Copyright (C) 2016-2022, 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
@@ -51,8 +51,6 @@ explicit WinDbg ;
mp-run-simple has_windbg_cached.cpp : : : <library>Dbgeng <library>ole32 : WinDbgCached ;
explicit WinDbgCached ;
local libraries ;
lib boost_stacktrace_noop
: # sources
../src/noop.cpp
@@ -64,8 +62,6 @@ lib boost_stacktrace_noop
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
;
libraries += boost_stacktrace_noop ;
lib boost_stacktrace_backtrace
: # sources
../src/backtrace.cpp
@@ -80,8 +76,6 @@ lib boost_stacktrace_backtrace
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
;
libraries += boost_stacktrace_backtrace ;
lib boost_stacktrace_addr2line
: # sources
../src/addr2line.cpp
@@ -95,8 +89,6 @@ lib boost_stacktrace_addr2line
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
;
libraries += boost_stacktrace_addr2line ;
lib boost_stacktrace_basic
: # sources
../src/basic.cpp
@@ -110,8 +102,6 @@ lib boost_stacktrace_basic
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
;
libraries += boost_stacktrace_basic ;
lib boost_stacktrace_windbg
: # sources
../src/windbg.cpp
@@ -125,8 +115,6 @@ lib boost_stacktrace_windbg
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
;
libraries += boost_stacktrace_windbg ;
lib boost_stacktrace_windbg_cached
: # sources
../src/windbg_cached.cpp
@@ -140,6 +128,4 @@ lib boost_stacktrace_windbg_cached
#<link>shared:<define>BOOST_STACKTRACE_DYN_LINK=1
;
libraries += boost_stacktrace_windbg_cached ;
boost-install $(libraries) ;
boost-install boost_stacktrace_noop boost_stacktrace_backtrace boost_stacktrace_addr2line boost_stacktrace_basic boost_stacktrace_windbg boost_stacktrace_windbg_cached ;

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2020.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,10 +1,15 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// 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 <backtrace.h>
#ifdef BOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE
# include BOOST_STACKTRACE_BACKTRACE_INCLUDE_FILE
#else
# include <backtrace.h>
#endif
#include <unwind.h>
int main() {

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2020.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2020.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
# Copyright Antony Polukhin 2016-2018.
# Copyright Antony Polukhin, 2016-2023.
# 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)

View File

@@ -2,7 +2,7 @@
[quickbook 1.6]
[version 1.0]
[id stacktrace]
[copyright 2016-2018 Antony Polukhin]
[copyright 2016-2023 Antony Polukhin]
[category Language Features Emulation]
[license
Distributed under the Boost Software License, Version 1.0.
@@ -57,53 +57,6 @@ Code from above will output something like this:
[note By default the Stacktrace library is very conservative in methods to decode stacktrace. If your output does not look as fancy as in example from above, see [link stacktrace.configuration_and_build section "Configuration and Build"] for allowing advanced features of the library. ]
[endsect]
[section Handle terminates, aborts and Segmentation Faults]
Segmentation Faults and `std::terminate` calls sometimes happen in programs. Programmers usually wish to get as much information as possible on such incidents, so having a stacktrace will significantly improve debugging and fixing.
`std::terminate` calls `std::abort`, so we need to capture stack traces on Segmentation Faults and Abort signals.
[warning Writing a signal handler requires high attention! Only a few system calls allowed in signal handlers, so there's no cross platform way to print a stacktrace without a risk of deadlocking. The only way to deal with the problem - [*dump raw stacktrace into file/socket and parse it on program restart].]
[warning Not all the platforms provide means for even getting stacktrace in async signal safe way. No stack trace will be saved on such platforms. ]
Let's write a handler to safely dump stacktrace:
[getting_started_terminate_handlers]
Registering our handler:
[getting_started_setup_handlers]
At program start we check for a file with stacktrace and if it exist - we're writing it in human readable format:
[getting_started_on_program_restart]
Now we'll get the following output on `std::terminate` call after the program restarts:
```
Previous run crashed:
0# 0x00007F2EC0A6A8EF
1# my_signal_handler(int) at ../example/terminate_handler.cpp:37
2# 0x00007F2EBFD84CB0
3# 0x00007F2EBFD84C37
4# 0x00007F2EBFD88028
5# 0x00007F2EC0395BBD
6# 0x00007F2EC0393B96
7# 0x00007F2EC0393BE1
8# bar(int) at ../example/terminate_handler.cpp:18
9# foo(int) at ../example/terminate_handler.cpp:22
10# bar(int) at ../example/terminate_handler.cpp:14
11# foo(int) at ../example/terminate_handler.cpp:22
12# main at ../example/terminate_handler.cpp:84
13# 0x00007F2EBFD6FF45
14# 0x0000000000402209
```
[note Function names from shared libraries may not be decoded due to address space layout randomization. Still better than nothing.]
[endsect]
[section Better asserts]
@@ -137,12 +90,50 @@ Backtrace:
Now we do know the steps that led to the assertion and can find the error without debugger.
[endsect]
[section Handle terminates]
`std::terminate` calls sometimes happen in programs. Programmers usually wish to get as much information as possible on such incidents, so having a stacktrace significantly improves debugging and fixing.
Here's how to write a terminate handler that dumps stacktrace:
[getting_started_terminate_handlers]
Here's how to register it:
[getting_started_setup_terminate_handlers]
Now we'll get the following output on `std::terminate` call:
```
Previous run crashed:
0# my_terminate_handler(int) at ../example/terminate_handler.cpp:37
1# __cxxabiv1::__terminate(void (*)()) at ../../../../src/libstdc++-v3/libsupc++/eh_terminate.cc:48
2# 0x00007F3CE65E5901 in /usr/lib/x86_64-linux-gnu/libstdc++.so.6
3# bar(int) at ../example/terminate_handler.cpp:18
4# foo(int) at ../example/terminate_handler.cpp:22
5# bar(int) at ../example/terminate_handler.cpp:14
6# foo(int) at ../example/terminate_handler.cpp:22
7# main at ../example/terminate_handler.cpp:84
8# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6
9# 0x0000000000402209
```
[warning There's a temptation to write a signal handler that prints the stacktrace on `SIGSEGV` or abort. Unfortunately, there's no cross platform way to do that without a risk of deadlocking. Not all the platforms provide means for even getting stacktrace in async signal safe way.
Signal handler is often invoked on a separate stack and trash is returned on attempt to get a trace!
Generic recommendation is to *avoid signal handlers! Use* platform specific ways to store and decode *core files*.
]
[endsect]
[section Exceptions with stacktrace]
You can provide more information along with exception by embedding stacktraces into the exception. There are many ways to do that, here's how to doe that using Boost.Exception:
You can provide more information along with exception by embedding stacktraces into the exception. There are many ways to do that, here's how to do that using Boost.Exception:
* Declare a `boost::error_info` typedef that holds the stacktrace:
@@ -294,11 +285,11 @@ 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:
[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 `-fisibility=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 COM to show debug info. May require linking with *ole32* and *dbgeng*. ] [MSVC, MinGW-w64, Intel on Windows] [yes] [no]]
[[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. 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 COM to show debug info and caches COM instances in TLS for better performance. Useful only for cases when traces are gathered very often. [footnote This may affect other components of your program that use COM, because this mode calls the `CoInitializeEx(0, COINIT_MULTITHREADED)` on first use and does not call `::CoUninitialize();` until the current thread is destroyed. ] 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. *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_WINDBG_CACHED*] [*boost_stacktrace_windbg_cached*] [ Uses `dbgeng.h` to show debug info and caches 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.
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]]
@@ -330,6 +321,17 @@ Let's assume that you've installed MinGW into C:\MinGW and downloaded [@https://
[endsect]
[section Windows deployment and symbol files]
Function names may not be resolved after deployment of your application to a different system.
There are multiple ways to deal with that issue if you distribute PDB files along with your application:
* Link your application and shared libraries with a properly set `/PDBALTPATH` flag, for example `/PDBALTPATH:%_PDB%`. See [@https://docs.microsoft.com/en-us/cpp/build/reference/pdbaltpath-use-alternate-pdb-path official documentation for more info].
* Set the `_NT_ALT_SYMBOL_PATH` or `_NT_SYMBOL_PATH` environment variables of the target system to the path of the PDBs. See [@https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/symbol-path#controlling-the-symbol-path official documentation for more info].
[endsect]
[endsect]
[section Acknowledgements]

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -24,9 +24,6 @@ BOOST_NOINLINE void foo(int i) {
bar(--i);
}
namespace std { inline void ignore_abort(){ std::exit(0); } }
#define abort ignore_abort
//[getting_started_assert_handlers
// BOOST_ENABLE_ASSERT_DEBUG_HANDLER is defined for the whole project
@@ -38,7 +35,8 @@ namespace boost {
inline void assertion_failed_msg(char const* expr, char const* msg, char const* function, char const* /*file*/, long /*line*/) {
std::cerr << "Expression '" << expr << "' is false in function '" << function << "': " << (msg ? msg : "<...>") << ".\n"
<< "Backtrace:\n" << boost::stacktrace::stacktrace() << '\n';
std::abort();
/*<-*/ std::exit(0); /*->*/
/*=std::abort();*/
}
inline void assertion_failed(char const* expr, char const* function, char const* file, long line) {

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -23,25 +23,44 @@ BOOST_NOINLINE void foo(int i) {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//[getting_started_terminate_handlers
//[getting_started_signal_handlers
#include <signal.h> // ::signal, ::raise
#include <boost/stacktrace.hpp>
void my_signal_handler(int signum) {
::signal(signum, SIG_DFL);
// Outputs nothing or trash on majority of platforms
boost::stacktrace::safe_dump_to("./backtrace.dump");
::raise(SIGABRT);
}
//]
void setup_handlers() {
//[getting_started_setup_handlers
//[getting_started_setup_signel_handlers
::signal(SIGSEGV, &my_signal_handler);
::signal(SIGABRT, &my_signal_handler);
//]
}
//[getting_started_terminate_handlers
#include <cstdlib> // std::abort
#include <exception> // std::set_terminate
#include <iostream> // std::cerr
#include <boost/stacktrace.hpp>
void my_terminate_handler() {
try {
std::cerr << boost::stacktrace::stacktrace();
} catch (...) {}
std::abort();
}
//]
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOST_CONSTEXPR_OR_CONST std::size_t shared_memory_size = 4096 * 8;
@@ -58,7 +77,7 @@ boost::interprocess::mapped_region g_region; // inited at program start
void my_signal_handler2(int signum) {
::signal(signum, SIG_DFL);
void** f = static_cast<void**>(g_region.get_address());
*f = reinterpret_cast<void*>(1); // Setting flag that shared memory now constains stacktrace.
*f = reinterpret_cast<void*>(1); // Setting flag that shared memory now contains stacktrace.
boost::stacktrace::safe_dump_to(f + 1, g_region.get_size() - sizeof(void*));
::raise(SIGABRT);
@@ -92,6 +111,15 @@ inline void copy_and_run(const char* exec_name, char param, bool not_null) {
}
}
int run_0(const char* /*argv*/[]) {
//[getting_started_setup_terminate_handlers
std::set_terminate(&my_terminate_handler);
//]
foo(5);
return 1;
}
int run_1(const char* /*argv*/[]) {
setup_handlers();
foo(5);
@@ -168,8 +196,8 @@ int run_4(const char* argv[]) {
//[getting_started_on_program_restart_shmem
void** f = static_cast<void**>(g_region.get_address());
if (*f) { // Checking if memory constains stacktrace.
boost::stacktrace::stacktrace st
if (*f) { // Checking if memory contains stacktrace.
boost::stacktrace::stacktrace st
= boost::stacktrace::stacktrace::from_dump(f + 1, g_region.get_size() - sizeof(bool));
std::cout << "Previous run crashed and left trace in shared memory:\n" << st << std::endl;
@@ -300,7 +328,10 @@ int test_inplace() {
int main(int argc, const char* argv[]) {
if (argc < 2) {
// On Windows the debugger could be active. In that case tests hang and the CI run fails.
#ifndef BOOST_WINDOWS
copy_and_run(argv[0], '0', true);
// We are copying files to make sure that stacktrace printing works independently from executable name
copy_and_run(argv[0], '1', true);
copy_and_run(argv[0], '2', false);
@@ -314,6 +345,7 @@ int main(int argc, const char* argv[]) {
}
switch (argv[1][0]) {
case '0': return run_0(argv);
case '1': return run_1(argv);
case '2': return run_2(argv);
case '3': return run_3(argv);

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -35,7 +35,7 @@ BOOST_NOINLINE void oops(int i) {
if (i >= 4)
throw_with_trace(std::out_of_range("'i' must be less than 4 in oops()"));
if (i <= 0)
throw_with_trace(std::logic_error("'i' must not be greater than zero in oops()"));
throw_with_trace(std::logic_error("'i' must be greater than zero in oops()"));
//]
foo(i);
std::exit(1);

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,7 +13,7 @@
#endif
#include <boost/stacktrace/frame.hpp>
#include <boost/stacktrace/stacktrace.hpp>
#include <boost/stacktrace/stacktrace.hpp> // Actually already includes all the headers
#include <boost/stacktrace/safe_dump_to.hpp>
#endif // BOOST_STACKTRACE_HPP

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -14,7 +14,19 @@
#include <boost/stacktrace/safe_dump_to.hpp>
// On iOS 32-bit ARM architecture _Unwind_Backtrace function doesn't exist, symbol is undefined.
// Forcing libc backtrace() function usage.
#include <boost/predef.h>
#if defined(BOOST_OS_IOS_AVAILABLE) && defined(BOOST_ARCH_ARM_AVAILABLE) && BOOST_VERSION_NUMBER_MAJOR(BOOST_ARCH_ARM) < 8
#define BOOST_STACKTRACE_USE_LIBC_BACKTRACE_FUNCTION
#endif
#if defined(BOOST_STACKTRACE_USE_LIBC_BACKTRACE_FUNCTION)
#include <execinfo.h>
#include <algorithm>
#else
#include <unwind.h>
#endif
#include <cstdio>
#if !defined(_GNU_SOURCE) && !defined(BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED) && !defined(BOOST_WINDOWS)
@@ -23,6 +35,7 @@
namespace boost { namespace stacktrace { namespace detail {
#if !defined(BOOST_STACKTRACE_USE_LIBC_BACKTRACE_FUNCTION)
struct unwind_state {
std::size_t frames_to_skip;
native_frame_ptr_t* current;
@@ -48,16 +61,35 @@ inline _Unwind_Reason_Code unwind_callback(::_Unwind_Context* context, void* arg
}
return ::_URC_NO_REASON;
}
#endif //!defined(BOOST_STACKTRACE_USE_LIBC_BACKTRACE_FUNCTION)
std::size_t this_thread_frames::collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) BOOST_NOEXCEPT {
std::size_t frames_count = 0;
if (!max_frames_count) {
return frames_count;
}
skip += 1;
boost::stacktrace::detail::unwind_state state = { skip + 1, out_frames, out_frames + max_frames_count };
#if defined(BOOST_STACKTRACE_USE_LIBC_BACKTRACE_FUNCTION)
// According to https://opensource.apple.com/source/Libc/Libc-1272.200.26/gen/backtrace.c.auto.html
// it looks like the `::backtrace` is async signal safe.
frames_count = static_cast<size_t>(::backtrace(const_cast<void **>(out_frames), static_cast<int>(max_frames_count)));
// NOTE: There is no way to pass "skip" count to backtrace function so we need to perform left shift operation.
// If number of elements in result backtrace is >= max_frames_count then "skip" elements are wasted.
if (frames_count && skip) {
if (skip >= frames_count) {
frames_count = 0;
} else {
std::copy(out_frames + skip, out_frames + frames_count, out_frames);
frames_count -= skip;
}
}
#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;
#endif //defined(BOOST_STACKTRACE_USE_LIBC_BACKTRACE_FUNCTION)
if (frames_count && out_frames[frames_count - 1] == 0) {
-- frames_count;
@@ -69,4 +101,6 @@ std::size_t this_thread_frames::collect(native_frame_ptr_t* out_frames, std::siz
}}} // namespace boost::stacktrace::detail
#undef BOOST_STACKTRACE_USE_LIBC_BACKTRACE_FUNCTION
#endif // BOOST_STACKTRACE_DETAIL_COLLECT_UNWIND_IPP

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -44,37 +44,12 @@
namespace boost { namespace stacktrace { namespace detail {
class com_global_initer: boost::noncopyable {
bool ok_;
public:
com_global_initer() BOOST_NOEXCEPT
: ok_(false)
{
// COINIT_MULTITHREADED means that we must serialize access to the objects manually.
// This is the fastest way to work. If user calls CoInitializeEx before us - we
// can end up with other mode (which is OK for us).
//
// If we call CoInitializeEx befire user - user may end up with different mode, which is a problem.
// So we need to call that initialization function as late as possible.
const DWORD res = ::CoInitializeEx(0, COINIT_MULTITHREADED);
ok_ = (res == S_OK || res == S_FALSE);
}
~com_global_initer() BOOST_NOEXCEPT {
if (ok_) {
::CoUninitialize();
}
}
};
template <class T>
class com_holder: boost::noncopyable {
T* holder_;
public:
com_holder(const com_global_initer&) BOOST_NOEXCEPT
com_holder() BOOST_NOEXCEPT
: holder_(0)
{}
@@ -98,7 +73,7 @@ public:
};
static std::string mingw_demangling_workaround(const std::string& s) {
inline std::string mingw_demangling_workaround(const std::string& s) {
#ifdef BOOST_GCC
if (s.empty()) {
return s;
@@ -114,14 +89,25 @@ static std::string mingw_demangling_workaround(const std::string& s) {
#endif
}
inline void trim_right_zeroes(std::string& s) {
// MSVC-9 does not have back() and pop_back() functions in std::string
while (!s.empty()) {
const std::size_t last = static_cast<std::size_t>(s.size() - 1);
if (s[last] != '\0') {
break;
}
s.resize(last);
}
}
class debugging_symbols: boost::noncopyable {
static void try_init_com(com_holder< ::IDebugSymbols>& idebug, const com_global_initer& com) BOOST_NOEXCEPT {
com_holder< ::IDebugClient> iclient(com);
static void try_init_com(com_holder< ::IDebugSymbols>& idebug) BOOST_NOEXCEPT {
com_holder< ::IDebugClient> iclient;
if (S_OK != ::DebugCreate(__uuidof(IDebugClient), iclient.to_void_ptr_ptr())) {
return;
}
com_holder< ::IDebugControl> icontrol(com);
com_holder< ::IDebugControl> icontrol;
const bool res0 = (S_OK == iclient->QueryInterface(
__uuidof(IDebugControl),
icontrol.to_void_ptr_ptr()
@@ -143,20 +129,17 @@ class debugging_symbols: boost::noncopyable {
return;
}
// No cheking: QueryInterface sets the output parameter to NULL in case of error.
// No checking: QueryInterface sets the output parameter to NULL in case of error.
iclient->QueryInterface(__uuidof(IDebugSymbols), idebug.to_void_ptr_ptr());
}
#ifndef BOOST_STACKTRACE_USE_WINDBG_CACHED
boost::stacktrace::detail::com_global_initer com_;
com_holder< ::IDebugSymbols> idebug_;
public:
debugging_symbols() BOOST_NOEXCEPT
: com_()
, idebug_(com_)
{
try_init_com(idebug_, com_);
try_init_com(idebug_);
}
#else
@@ -168,11 +151,10 @@ public:
static com_holder< ::IDebugSymbols>& get_thread_local_debug_inst() BOOST_NOEXCEPT {
// [class.mfct]: A static local variable or local type in a member function always refers to the same entity, whether
// or not the member function is inline.
static thread_local boost::stacktrace::detail::com_global_initer com;
static thread_local com_holder< ::IDebugSymbols> idebug(com);
static thread_local com_holder< ::IDebugSymbols> idebug;
if (!idebug.is_inited()) {
try_init_com(idebug, com);
try_init_com(idebug);
}
return idebug;
@@ -217,8 +199,12 @@ public:
&size,
0
));
// According to https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/dbgeng/nf-dbgeng-idebugsymbols-getnamebyoffset
// "This size includes the space for the '\0' terminating character."
result.resize(size - 1);
} else if (res) {
result = name;
result.assign(name, size - 1);
}
if (!res) {
@@ -301,6 +287,7 @@ public:
&size,
0
));
trim_right_zeroes(result.first);
result.second = line_num;
if (!res) {

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -59,6 +59,9 @@ public:
std::string to_string(const frame* frames, std::size_t size) {
std::string res;
if (size == 0) {
return res;
}
res.reserve(64 * size);
to_string_impl impl;
@@ -82,6 +85,10 @@ std::string to_string(const frame* frames, std::size_t size) {
std::string frame::name() const {
if (!addr_) {
return std::string();
}
#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
@@ -93,6 +100,10 @@ std::string frame::name() const {
}
std::string to_string(const frame& f) {
if (!f) {
return std::string();
}
boost::stacktrace::detail::to_string_impl impl;
return impl(f.address());
}

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -82,31 +82,35 @@ BOOST_SYMBOL_VISIBLE inline ::backtrace_state* construct_state(const program_loc
//
//
// Unfortunately, that solution segfaults when `construct_state()` function is in .so file
// and multiple threads concurrently work with state.
// and multiple threads concurrently work with state. I failed to localize the root cause:
// https://gcc.gnu.org/bugzilla//show_bug.cgi?id=87653
#define BOOST_STACKTRACE_DETAIL_IS_MT 1
#ifndef BOOST_HAS_THREADS
static
#if !defined(BOOST_HAS_THREADS)
# define BOOST_STACKTRACE_DETAIL_STORAGE static
# undef BOOST_STACKTRACE_DETAIL_IS_MT
# define BOOST_STACKTRACE_DETAIL_IS_MT 0
#elif defined(BOOST_STACKTRACE_BACKTRACE_FORCE_STATIC)
# define BOOST_STACKTRACE_DETAIL_STORAGE static
#elif !defined(BOOST_NO_CXX11_THREAD_LOCAL)
# define BOOST_STACKTRACE_DETAIL_STORAGE thread_local
#elif defined(__GNUC__) && !defined(__clang__)
# define BOOST_STACKTRACE_DETAIL_STORAGE static __thread
#else
// Result of `construct_state()` invocation is not stored by the callers, so `thread_local`
// gives a single `state` per thread and that state is not shared between threads in any way.
# ifndef BOOST_NO_CXX11_THREAD_LOCAL
thread_local
# elif defined(__GNUC__)
static __thread
# else
/* just a local variable */
# endif
# define BOOST_STACKTRACE_DETAIL_STORAGE /* just a local variable */
#endif
::backtrace_state* state = ::backtrace_create_state(
BOOST_STACKTRACE_DETAIL_STORAGE ::backtrace_state* state = ::backtrace_create_state(
prog_location.name(),
0,
BOOST_STACKTRACE_DETAIL_IS_MT,
boost::stacktrace::detail::libbacktrace_error_callback,
0
);
#undef BOOST_STACKTRACE_DETAIL_IS_MT
#undef BOOST_STACKTRACE_DETAIL_STORAGE
return state;
}
@@ -195,6 +199,10 @@ inline std::string name_impl(const void* addr) {
std::string frame::source_file() const {
std::string res;
if (!addr_) {
return res;
}
boost::stacktrace::detail::program_location prog_location;
::backtrace_state* state = boost::stacktrace::detail::construct_state(prog_location);
@@ -213,6 +221,10 @@ std::string frame::source_file() const {
}
std::size_t frame::source_line() const {
if (!addr_) {
return 0;
}
boost::stacktrace::detail::program_location prog_location;
::backtrace_state* state = boost::stacktrace::detail::construct_state(prog_location);

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -31,7 +31,7 @@ inline boost::array<char, 40> to_dec_array(std::size_t value) BOOST_NOEXCEPT {
}
for (std::size_t i = 1; i <= digits; ++i) {
ret[digits - i] = '0' + (value % 10);
ret[digits - i] = static_cast<char>('0' + (value % 10));
value /= 10;
}

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,5 +1,5 @@
// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
// Copyright 2015-2018 Antony Polukhin.
// Copyright Antony Polukhin, 2015-2023.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,6 +12,24 @@
# pragma once
#endif
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) || \
defined(BOOST_NO_CXX11_CONSTEXPR) || \
defined(BOOST_NO_CXX11_NULLPTR) || \
defined(BOOST_NO_CXX11_NOEXCEPT) || \
defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || \
defined(BOOST_NO_CXX11_FINAL) || \
defined(BOOST_NO_CXX11_ALIGNOF) || \
defined(BOOST_NO_CXX11_STATIC_ASSERT) || \
defined(BOOST_NO_CXX11_SMART_PTR) || \
defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) || \
defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
BOOST_PRAGMA_MESSAGE("C++03 support is deprecated in Boost.Stacktrace 1.82 and will be removed in Boost.Stacktrace 1.84.")
#endif
#include <iosfwd>
#include <string>

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,7 @@
#endif
#include <boost/core/explicit_operator_bool.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/container_hash/hash_fwd.hpp>
#include <iosfwd>
@@ -26,6 +27,7 @@
#include <boost/stacktrace/stacktrace_fwd.hpp>
#include <boost/stacktrace/safe_dump_to.hpp>
#include <boost/stacktrace/detail/frame_decl.hpp>
#include <boost/stacktrace/frame.hpp>
#ifdef BOOST_INTEL
# pragma warning(push)
@@ -69,7 +71,7 @@ class basic_stacktrace {
return;
}
try {
BOOST_TRY {
{ // Fast path without additional allocations
native_frame_ptr_t buffer[buffer_size];
const std::size_t frames_count = boost::stacktrace::detail::this_thread_frames::collect(buffer, buffer_size < max_depth ? buffer_size : max_depth, frames_to_skip + 1);
@@ -95,9 +97,10 @@ class basic_stacktrace {
buf.resize(buf.size() * 2);
} while (buf.size() < buf.max_size()); // close to `true`, but suppresses `C4127: conditional expression is constant`.
} catch (...) {
} BOOST_CATCH (...) {
// ignore exception
}
BOOST_CATCH_END
}
/// @endcond
@@ -132,7 +135,7 @@ public:
///
/// @b Async-Handler-Safety: Safe if Allocator construction, copying, Allocator::allocate and Allocator::deallocate are async signal safe.
///
/// @param a Allocator that would be passed to underlying storeage.
/// @param a Allocator that would be passed to underlying storage.
BOOST_FORCEINLINE explicit basic_stacktrace(const allocator_type& a) BOOST_NOEXCEPT
: impl_(a)
{
@@ -149,7 +152,7 @@ public:
///
/// @param max_depth Max call sequence depth to collect.
///
/// @param a Allocator that would be passed to underlying storeage.
/// @param a Allocator that would be passed to underlying storage.
///
/// @throws Nothing. Note that default construction of allocator may throw, however it is
/// performed outside the constructor and exception in `allocator_type()` would not result in calling `std::terminate`.
@@ -317,7 +320,7 @@ public:
/// Constructs stacktrace from raw memory dump. Terminating zero frame is discarded.
///
/// @param begin Begining of the memory where the stacktrace was saved using the boost::stacktrace::safe_dump_to
/// @param begin Beginning of the memory where the stacktrace was saved using the boost::stacktrace::safe_dump_to
///
/// @param buffer_size_in_bytes Size of the memory. Usually the same value that was passed to the boost::stacktrace::safe_dump_to
///

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
<!DOCTYPE html>
<!--
Copyright (c) 2014-2018 Antony Polukhin
Copyright (c) Antony Polukhin, 2014-2023
antoshkka at gmail dot com
Distributed under the Boost Software License,
@@ -10,7 +10,7 @@
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; url=../../doc/html/stacktrace.html">
<meta http-equiv="refresh" content="0; url=https://www.boost.org/doc/libs/master/doc/html/stacktrace.html">
<title>Boost.Stacktrace</title>
<style>
body {
@@ -26,10 +26,10 @@
<body>
<p>
Automatic redirection failed, please go to
<a href="../../doc/html/stacktrace.html">../../doc/html/stacktrace.html</a>
<a href="https://www.boost.org/doc/libs/master/doc/html/stacktrace.html">https://www.boost.org/doc/libs/master/doc/html/stacktrace.html</a>
</p>
<p>
&copy; 2014-2018 Antony Polukhin
&copy; Antony Polukhin, 2014-2023
</p>
</body>
</html>

View File

@@ -8,7 +8,7 @@
"Antony Polukhin <antoshkka -at- gmail.com>"
],
"description": "Gather, store, copy and print backtraces.",
"std": [ "proposal" ],
"std": [ "c++23" ],
"category": [
"System", "Correctness"
]

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2020.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2020.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2020.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2020.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2020.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2020.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,10 +1,12 @@
# Copyright (C) 2016-2018, Antony Polukhin.
# Copyright (C) 2016-2021, 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 ../../config/checks/config : requires ;
lib dl : : <link>shared ;
lib gcc_s ;
lib rt ;
@@ -37,7 +39,9 @@ local FORCE_SYMBOL_EXPORT = <target-os>freebsd:<linkflags>"-rdynamic" <target-os
<define>BOOST_STACKTRACE_TEST_EXPORTS_TABLE_USAGE ;
local BT_DEPS = <target-os>linux:<library>dl <library>backtrace [ check-target-builds ../build//libbacktrace : : <build>no ] ;
local AD2L_DEPS = <target-os>linux:<library>dl [ check-target-builds ../build//addr2line : : <build>no ] ;
local AD2L_DEPS = <target-os>linux:<library>dl [ check-target-builds ../build//addr2line : : <build>no ]
<define>BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL # Some old versions of addr2line may not produce readable names for a modern compilers
;
local WIND_DEPS = <library>Dbgeng <library>ole32 [ check-target-builds ../build//WinDbg : : <build>no ] ;
local WICA_DEPS = <library>Dbgeng <library>ole32 [ check-target-builds ../build//WinDbgCached : : <build>no ] ;
local NOOP_DEPS = ;
@@ -77,6 +81,7 @@ test-suite stacktrace_tests
# Header only tests with debug symbols
[ run test.cpp test_impl.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_BACKTRACE $(BT_DEPS) : backtrace_ho ]
[ run test.cpp test_impl.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_BACKTRACE <define>BOOST_STACKTRACE_BACKTRACE_FORCE_STATIC $(BT_DEPS) : backtrace_ho_static ]
[ run test.cpp test_impl.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_ADDR2LINE $(AD2L_DEPS) : addr2line_ho ]
[ run test_noop.cpp test_impl.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_NOOP $(NOOP_DEPS) : noop_ho ]
[ run test.cpp test_impl.cpp : : : <debug-symbols>on $(WIND_DEPS) : windbg_ho ]
@@ -84,6 +89,15 @@ test-suite stacktrace_tests
[ run test.cpp test_impl.cpp : : : <debug-symbols>on $(FORCE_SYMBOL_EXPORT) $(BASIC_DEPS) : basic_ho ]
[ run test.cpp test_impl.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL $(BASIC_DEPS) : basic_ho_empty ]
# Header only trivial
[ run test_trivial.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_BACKTRACE $(BT_DEPS) : trivial_backtrace_ho ]
[ run test_trivial.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_ADDR2LINE $(AD2L_DEPS) : trivial_addr2line_ho ]
[ run test_trivial.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_NOOP $(NOOP_DEPS) : trivial_noop_ho ]
[ run test_trivial.cpp : : : <debug-symbols>on $(WIND_DEPS) : trivial_windbg_ho ]
[ run test_trivial.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_USE_WINDBG_CACHED $(WICA_DEPS) : trivial_windbg_cached_ho ]
[ run test_trivial.cpp : : : <debug-symbols>on $(FORCE_SYMBOL_EXPORT) $(BASIC_DEPS) : trivial_basic_ho ]
[ run test_trivial.cpp : : : <debug-symbols>on <define>BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL $(BASIC_DEPS) : trivial_basic_ho_empty ]
# Test with shared linked implementations with debug symbols
[ run test.cpp : : : <debug-symbols>on <library>.//test_impl_lib_backtrace $(LINKSHARED_BT) : backtrace_lib ]
[ run test.cpp : : : <debug-symbols>on <library>.//test_impl_lib_addr2line $(LINKSHARED_AD2L) : addr2line_lib ]
@@ -92,10 +106,22 @@ test-suite stacktrace_tests
[ run test_noop.cpp : : : <debug-symbols>on <library>.//test_impl_lib_noop $(LINKSHARED_NOOP) : noop_lib ]
[ run test.cpp : : : <debug-symbols>on <library>.//test_impl_lib_basic $(LINKSHARED_BASIC) : basic_lib ]
# Trivial test with shared linked implementations with debug symbols
[ run test_trivial.cpp : : : <debug-symbols>on <library>.//test_impl_lib_backtrace $(LINKSHARED_BT) : trivial_backtrace_lib ]
[ run test_trivial.cpp : : : <debug-symbols>on <library>.//test_impl_lib_addr2line $(LINKSHARED_AD2L) : trivial_addr2line_lib ]
[ run test_trivial.cpp : : : <debug-symbols>on <library>.//test_impl_lib_windbg $(LINKSHARED_WIND) : trivial_windbg_lib ]
[ run test_trivial.cpp : : : <debug-symbols>on <library>.//test_impl_lib_windbg_cached $(LINKSHARED_WIND_CACHED) : trivial_windbg_cached_lib ]
[ run test_trivial.cpp : : : <debug-symbols>on <library>.//test_impl_lib_noop $(LINKSHARED_NOOP) : trivial_noop_lib ]
[ run test_trivial.cpp : : : <debug-symbols>on <library>.//test_impl_lib_basic $(LINKSHARED_BASIC) : trivial_basic_lib ]
# Thread safety with debug symbols
[ run thread_safety_checking.cpp
: : : <debug-symbols>on <library>/boost/thread//boost_thread <library>/boost/timer//boost_timer <library>.//test_impl_lib_backtrace $(LINKSHARED_BT)
: backtrace_lib_threaded ]
[ run thread_safety_checking.cpp
: : : <debug-symbols>on <library>/boost/thread//boost_thread <library>/boost/timer//boost_timer <library>.//test_impl_lib_backtrace $(LINKSHARED_BT)
<define>BOOST_STACKTRACE_BACKTRACE_FORCE_STATIC
: backtrace_lib_threaded_static ]
[ run thread_safety_checking.cpp
: : : <debug-symbols>on <library>/boost/thread//boost_thread <library>/boost/timer//boost_timer <library>.//test_impl_lib_windbg $(LINKSHARED_WIND)
: windbg_lib_threaded ]
@@ -106,15 +132,6 @@ test-suite stacktrace_tests
: : : <debug-symbols>on <library>/boost/thread//boost_thread <library>/boost/timer//boost_timer <library>.//test_impl_lib_basic $(LINKSHARED_BASIC)
: basic_lib_threaded ]
[ run thread_safety_checking.cpp
: : : <debug-symbols>on <library>/boost/thread//boost_thread <library>/boost/timer//boost_timer <library>.//test_impl_lib_windbg
$(LINKSHARED_WIND) <define>BOOST_STACKTRACE_TEST_COM_PREINIT_MT
: windbg_lib_threaded_com_mt ]
[ run thread_safety_checking.cpp
: : : <debug-symbols>on <library>/boost/thread//boost_thread <library>/boost/timer//boost_timer <library>.//test_impl_lib_windbg_cached
$(LINKSHARED_WIND_CACHED) <define>BOOST_STACKTRACE_TEST_COM_PREINIT_ST
: windbg_cached_lib_threaded_com_st ]
##### Tests with disabled debug symbols #####
# Header only tests without debug symbols
@@ -166,23 +183,6 @@ test-suite stacktrace_tests
$(LINKSHARED_BASIC)
: basic_lib_no_dbg_threaded ]
[ run thread_safety_checking.cpp
: : : <debug-symbols>off
<library>/boost/thread//boost_thread
<library>/boost/timer//boost_timer
<library>.//test_impl_lib_windbg
$(LINKSHARED_WIND)
<define>BOOST_STACKTRACE_TEST_COM_PREINIT_MT
: windbg_lib_threaded_com_mt ]
[ run thread_safety_checking.cpp
: : : <debug-symbols>off
<library>/boost/thread//boost_thread
<library>/boost/timer//boost_timer
<library>.//test_impl_lib_windbg_cached
$(LINKSHARED_WIND_CACHED)
<define>BOOST_STACKTRACE_TEST_COM_PREINIT_ST
: windbg_cached_lib_threaded_com_st ]
[ run test_void_ptr_cast.cpp ]
[ run test_num_conv.cpp ]
;
@@ -197,6 +197,11 @@ for local p in [ glob ../example/*.cpp ]
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 ] ;
}
stacktrace_tests += [ run $(p) : : : <debug-symbols>on $(LINKSHARED_BT) $(additional_dependency) : backtrace_$(p2[1]:B) ] ;
stacktrace_tests += [ run $(p) : : : <debug-symbols>on $(LINKSHARED_AD2L) $(additional_dependency) : addr2line_$(p[1]:B) ] ;
stacktrace_tests += [ run $(p) : : : <debug-symbols>on $(LINKSHARED_WIND) $(additional_dependency) : windbg_$(p[1]:B) ] ;

View File

@@ -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-2018.
# Copyright Antony Polukhin, 2016-2023.
#
# See https://svn.boost.org/trac/boost/wiki/TravisCoverals for description of this file

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -10,6 +10,8 @@
#include <stdexcept>
#include <iostream>
#include <sstream>
#include <cctype>
#include <boost/core/lightweight_test.hpp>
#include <boost/functional/hash.hpp>
@@ -45,6 +47,25 @@ void test_deeply_nested_namespaces() {
BOOST_TEST(ns1 != return_from_nested_namespaces()); // Different addresses in test_deeply_nested_namespaces() function
}
std::size_t count_unprintable_chars(const std::string& s) {
std::size_t result = 0;
for (std::size_t i = 0; i < s.size(); ++i) {
result += (std::isprint(s[i]) ? 0 : 1);
}
return result;
}
void test_frames_string_data_validity() {
stacktrace trace = return_from_nested_namespaces();
for (std::size_t i = 0; i < trace.size(); ++i) {
BOOST_TEST_EQ(count_unprintable_chars(trace[i].source_file()), 0);
BOOST_TEST_EQ(count_unprintable_chars(trace[i].name()), 0);
}
BOOST_TEST(to_string(trace).find('\0') == std::string::npos);
}
// Template parameter Depth is to produce different functions on each Depth. This simplifies debugging when one of the tests catches error
template <std::size_t Depth>
void test_nested(bool print = true) {
@@ -79,8 +100,6 @@ void test_nested(bool print = true) {
BOOST_TEST(ss1.str().find("function_from_main_translation_unit") != std::string::npos);
BOOST_TEST(ss2.str().find("function_from_main_translation_unit") != std::string::npos);
#endif
//BOOST_TEST(false);
}
template <class Bt>
@@ -208,9 +227,9 @@ void test_frame() {
boost::stacktrace::frame empty_frame;
BOOST_TEST(!empty_frame);
BOOST_TEST(empty_frame.source_file() == "");
BOOST_TEST(empty_frame.name() == "");
BOOST_TEST(empty_frame.source_line() == 0);
BOOST_TEST_EQ(empty_frame.source_file(), "");
BOOST_TEST_EQ(empty_frame.name(), "");
BOOST_TEST_EQ(empty_frame.source_line(), 0);
}
// Template parameter bool BySkip is to produce different functions on each BySkip. This simplifies debugging when one of the tests catches error
@@ -240,6 +259,7 @@ void test_empty_basic_stacktrace() {
int main() {
test_deeply_nested_namespaces();
test_frames_string_data_validity();
test_nested<15>();
test_comparisons();
test_iterators();

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

15
test/test_trivial.cpp Normal file
View File

@@ -0,0 +1,15 @@
// Copyright Antony Polukhin, 2022-2023.
//
// 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)
// See https://github.com/boostorg/stacktrace/issues/116
#include <boost/stacktrace/stacktrace.hpp>
#include <iostream>
int main() {
std::cout << boost::stacktrace::stacktrace() << std::endl;
}

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2018.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -41,18 +41,7 @@ void main_test_loop() {
}
}
#if defined(BOOST_STACKTRACE_TEST_COM_PREINIT_MT) || defined(BOOST_STACKTRACE_TEST_COM_PREINIT_ST)
# include <windows.h>
# include "dbgeng.h"
#endif
int main() {
#if defined(BOOST_STACKTRACE_TEST_COM_PREINIT_MT)
::CoInitializeEx(0, COINIT_MULTITHREADED);
#elif defined(BOOST_STACKTRACE_TEST_COM_PREINIT_ST)
::CoInitializeEx(0, COINIT_APARTMENTTHREADED);
#endif
boost::timer::auto_cpu_timer t;
boost::thread t1(main_test_loop);
@@ -64,9 +53,5 @@ int main() {
t2.join();
t3.join();
#if defined(BOOST_STACKTRACE_TEST_COM_PREINIT_MT) || defined(BOOST_STACKTRACE_TEST_COM_PREINIT_ST)
::CoUninitialize();
#endif
return boost::report_errors();
}