Compare commits

..

35 Commits

Author SHA1 Message Date
Antony Polukhin
4f2da0e653 Merge pull request #143 from francesco-ballarin/develop
Add missing cstdint include to detail/addr_base.hpp
2023-10-20 19:02:54 +03:00
Francesco Ballarin
8b1699c9d3 Add missing cstdint include to detail/addr_base.hpp 2023-10-01 10:14:34 +02:00
yhsb2k
dc5cd9d1f3 Fix build with MinGW-w64 12+. (#140)
For more details see: https://github.com/boostorg/stacktrace/issues/133

Accommodate mingw-llvm to this fix as well

macros defined by mingw-llvm 16 (https://github.com/mstorsjo/llvm-mingw):
#define __GNUC_MINOR__ 2
#define __GNUC_PATCHLEVEL__ 1
#define __GNUC__ 4

#define __clang_major__ 16
#define __clang_minor__ 0
#define __clang_patchlevel__ 0
2023-09-02 16:36:27 +03:00
ja2142
fbcd543b51 fix addr2line for pie binaries (#138) 2023-08-27 21:34:56 +03:00
Antony Polukhin
d849b145a6 disable some of the CI tests (2) 2023-08-27 18:27:41 +03:00
Antony Polukhin
760203fde5 disable some of the CI tests 2023-08-27 15:38:09 +03:00
Antony Polukhin
6a7510bd5e Do not produce and explicit hard error if compiler may not support some of the C++11 features 2023-08-27 15:26:56 +03:00
Antony Polukhin
959b65f303 CI fix attempt (3) 2023-08-26 21:18:46 +03:00
Antony Polukhin
d6320cc5a7 CI fix attempt (2) 2023-08-26 17:10:23 +03:00
Antony Polukhin
22a2c3920b CI fix attempt 2023-08-26 10:42:57 +03:00
Antony Polukhin
fc21c82b27 do not run tests on old MSVC in appveyor 2023-08-25 14:14:40 +03:00
Antony Polukhin
ae87ac9bcf update appveyor CI setup 2023-08-25 12:36:33 +03:00
Antony Polukhin
15b12e6e95 run tests on more compilers 2023-08-25 12:09:31 +03:00
Mohammad Nejati
34441a64c8 Use relative URL for redirect in index.html (#137) 2023-08-12 11:27:01 +03:00
Alex
abba18524f Modernize to cpp11 (#139)
Drop support for C++03

Boost.Stacktrace 1.84 now requires C++11.
2023-08-11 21:32:41 +03:00
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
50 changed files with 487 additions and 348 deletions

View File

@@ -17,23 +17,20 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
- toolset: gcc-9
- toolset: gcc-12
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
os: ubuntu-22.04
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
linkflags: "linkflags=--coverage -lasan -lubsan"
launcher: "testing.launcher=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.6"
gcov_tool: "gcov-10"
- toolset: clang
compiler: clang++-10
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-20.04
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"
@@ -88,9 +85,9 @@ jobs:
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.15.zip
unzip v1.15.zip
LCOV="`pwd`/lcov-1.15/bin/lcov --gcov-tool $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
@@ -114,10 +111,10 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: msvc-14.1
- toolset: msvc
cxxstd: "14,17,latest"
addrmd: 64
os: windows-2016
os: windows-2022
- toolset: msvc-14.2
cxxstd: "14,17,latest"
addrmd: 64

View File

@@ -22,13 +22,10 @@ function(stacktrace_add_library suffix opt libs defs)
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}

View File

@@ -1,13 +1,16 @@
# Copyright (C) 2016-2019, Antony Polukhin.
# Copyright (C) 2016-2023, 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 ;
project
: source-location .
: requirements
[ requires cxx11_rvalue_references ]
<visibility>hidden
;
@@ -51,8 +54,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 +65,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 +79,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 +92,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 +105,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 +118,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 +131,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,10 +1,15 @@
// Copyright Antony Polukhin, 2016-2020.
// 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-2022.
# 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-2022 Antony Polukhin]
[copyright 2016-2023 Antony Polukhin]
[category Language Features Emulation]
[license
Distributed under the Boost Software License, Version 1.0.
@@ -285,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]]

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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-2022.
// 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-2022.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -77,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);
@@ -196,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;

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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-2022.
// 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-2022.
// 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-2022.
// 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-2022.
// 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-2022.
// 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,7 @@
# pragma once
#endif
#include <boost/stacktrace/detail/addr_base.hpp>
#include <boost/stacktrace/detail/to_hex_array.hpp>
#include <boost/stacktrace/detail/to_dec_array.hpp>
#include <boost/stacktrace/detail/try_dec_convert.hpp>
@@ -28,7 +29,7 @@ namespace boost { namespace stacktrace { namespace detail {
#if defined(BOOST_STACKTRACE_ADDR2LINE_LOCATION) && !defined(BOOST_NO_CXX11_CONSTEXPR)
constexpr bool is_abs_path(const char* path) BOOST_NOEXCEPT {
constexpr bool is_abs_path(const char* path) noexcept {
return *path != '\0' && (
*path == ':' || *path == '/' || is_abs_path(path + 1)
);
@@ -41,7 +42,7 @@ class addr2line_pipe {
::pid_t pid;
public:
explicit addr2line_pipe(const char *flag, const char* exec_path, const char* addr) BOOST_NOEXCEPT
explicit addr2line_pipe(const char *flag, const char* exec_path, const char* addr) noexcept
: p(0)
, pid(0)
{
@@ -97,11 +98,11 @@ public:
::close(pdes[1]);
}
operator ::FILE*() const BOOST_NOEXCEPT {
operator ::FILE*() const noexcept {
return p;
}
~addr2line_pipe() BOOST_NOEXCEPT {
~addr2line_pipe() noexcept {
if (p) {
::fclose(p);
int pstat = 0;
@@ -155,6 +156,19 @@ inline std::string addr2line(const char* flag, const void* addr) {
return res;
}
inline std::string source_location(const void* addr, bool position_independent) {
uintptr_t addr_base = 0;
if (position_independent) {
addr_base = boost::stacktrace::detail::get_own_proc_addr_base(addr);
}
const void* offset = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) - addr_base);
std::string source_line = boost::stacktrace::detail::addr2line("-Cpe", reinterpret_cast<const void*>(offset));
if (source_line.empty() || source_line[0] == '?') {
return "";
}
return source_line;
}
struct to_string_using_addr2line {
std::string res;
@@ -163,9 +177,20 @@ struct to_string_using_addr2line {
}
bool prepare_source_location(const void* addr) {
//return addr2line("-Cfipe", addr); // Does not seem to work in all cases
std::string source_line = boost::stacktrace::detail::addr2line("-Cpe", addr);
if (!source_line.empty() && source_line[0] != '?') {
// general idea in all addr2line uses:
// in each case:
// - try to resolve whole address as if it was a non-pie binary
// - if that didn't work, try to resolve just an offset from binary base address
// this is needed because:
// - in pie binaries just passing an address to addr2line won't work (it needs an offset in this case)
// - in non-pie binaries whole address is needed (offset won't work)
// - there is no easy way to test if binary is position independent (that I know of)
std::string source_line = boost::stacktrace::detail::source_location(addr, false);
if(source_line.empty()) {
source_line = boost::stacktrace::detail::source_location(addr, true);
}
if (!source_line.empty()) {
res += " at ";
res += source_line;
return true;
@@ -178,8 +203,13 @@ struct to_string_using_addr2line {
template <class Base> class to_string_impl_base;
typedef to_string_impl_base<to_string_using_addr2line> to_string_impl;
inline std::string name_impl(const void* addr) {
std::string res = boost::stacktrace::detail::addr2line("-fe", addr);
inline std::string name(const void* addr, bool position_independent) {
uintptr_t addr_base = 0;
if(position_independent){
addr_base = boost::stacktrace::detail::get_own_proc_addr_base(addr);
}
const void* offset = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) - addr_base);
std::string res = boost::stacktrace::detail::addr2line("-fe", offset);
res = res.substr(0, res.find_last_of('\n'));
res = boost::core::demangle(res.c_str());
@@ -190,11 +220,23 @@ inline std::string name_impl(const void* addr) {
return res;
}
} // namespace detail
inline std::string name_impl(const void* addr) {
std::string res = boost::stacktrace::detail::name(addr, false);
if (res.empty()) {
res = boost::stacktrace::detail::name(addr, true);
}
std::string frame::source_file() const {
return res;
}
inline std::string source_file(const void* addr, bool position_independent) {
std::string res;
res = boost::stacktrace::detail::addr2line("-e", addr_);
uintptr_t addr_base = 0;
if(position_independent){
addr_base = boost::stacktrace::detail::get_own_proc_addr_base(addr);
}
const void* offset = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) - addr_base);
res = boost::stacktrace::detail::addr2line("-e", offset);
res = res.substr(0, res.find_last_of(':'));
if (res == "??") {
res.clear();
@@ -203,10 +245,14 @@ std::string frame::source_file() const {
return res;
}
std::size_t frame::source_line() const {
inline std::size_t source_line(const void* addr, bool position_independent) {
std::size_t line_num = 0;
std::string res = boost::stacktrace::detail::addr2line("-e", addr_);
uintptr_t addr_base = 0;
if(position_independent){
addr_base = boost::stacktrace::detail::get_own_proc_addr_base(addr);
}
const void* offset = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) - addr_base);
std::string res = boost::stacktrace::detail::addr2line("-e", offset);
const std::size_t last = res.find_last_of(':');
if (last == std::string::npos) {
return 0;
@@ -220,6 +266,27 @@ std::size_t frame::source_line() const {
return line_num;
}
} // namespace detail
std::string frame::source_file() const {
std::string res = boost::stacktrace::detail::source_file(addr_, false);
if (res.empty()) {
res = boost::stacktrace::detail::source_file(addr_, true);
}
return res;
}
std::size_t frame::source_line() const {
std::size_t line_num = boost::stacktrace::detail::source_line(addr_, false);
if (line_num == 0) {
line_num = boost::stacktrace::detail::source_line(addr_, true);
}
return line_num;
}
}} // namespace boost::stacktrace

View File

@@ -0,0 +1,89 @@
// 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)
#ifndef BOOST_STACKTRACE_DETAIL_ADDR_BASE_HPP
#define BOOST_STACKTRACE_DETAIL_ADDR_BASE_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#include <fstream>
#include <sstream>
#include <cstdint>
#include <cstdlib>
namespace boost { namespace stacktrace { namespace detail {
struct mapping_entry_t {
uintptr_t start = 0;
uintptr_t end = 0;
uintptr_t offset_from_base = 0;
inline bool contains_addr(const void* addr) const {
uintptr_t addr_uint = reinterpret_cast<uintptr_t>(addr);
return addr_uint >= start && addr_uint < end;
}
};
inline uintptr_t hex_str_to_int(const std::string& str) {
uintptr_t out;
std::stringstream ss;
ss << std::hex << str;
ss >> out;
if(ss.eof() && !ss.fail()) { // whole stream read, with no errors
return out;
} else {
throw std::invalid_argument(std::string("can't convert '") + str + "' to hex");
}
}
// parse line from /proc/<id>/maps
// format:
// 7fb60d1ea000-7fb60d20c000 r--p 00000000 103:02 120327460 /usr/lib/libc.so.6
// only parts 0 and 2 are interesting, these are:
// 0. mapping address range
// 2. mapping offset from base
inline mapping_entry_t parse_proc_maps_line(const std::string& line) {
std::string mapping_range_str, permissions_str, offset_from_base_str;
std::istringstream line_stream(line);
if(!std::getline(line_stream, mapping_range_str, ' ') ||
!std::getline(line_stream, permissions_str, ' ') ||
!std::getline(line_stream, offset_from_base_str, ' ')) {
return mapping_entry_t{};
}
std::string mapping_start_str, mapping_end_str;
std::istringstream mapping_range_stream(mapping_range_str);
if(!std::getline(mapping_range_stream, mapping_start_str, '-') ||
!std::getline(mapping_range_stream, mapping_end_str)) {
return mapping_entry_t{};
}
mapping_entry_t mapping{};
try {
mapping.start = hex_str_to_int(mapping_start_str);
mapping.end = hex_str_to_int(mapping_end_str);
mapping.offset_from_base = hex_str_to_int(offset_from_base_str);
return mapping;
} catch(std::invalid_argument& e) {
return mapping_entry_t{};
}
}
inline uintptr_t get_own_proc_addr_base(const void* addr) {
std::ifstream maps_file("/proc/self/maps");
for (std::string line; std::getline(maps_file, line); ) {
const mapping_entry_t mapping = parse_proc_maps_line(line);
if (mapping.contains_addr(addr)) {
return mapping.start - mapping.offset_from_base;
}
}
return 0;
}
}}} // namespace boost::stacktrace::detail
#endif // BOOST_STACKTRACE_DETAIL_ADDR_BASE_HPP

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -18,7 +18,7 @@
namespace boost { namespace stacktrace { namespace detail {
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 this_thread_frames::collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) noexcept {
return boost::winapi::RtlCaptureStackBackTrace(
static_cast<boost::winapi::ULONG_>(skip),
static_cast<boost::winapi::ULONG_>(max_frames_count),

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -16,7 +16,7 @@
namespace boost { namespace stacktrace { namespace detail {
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 this_thread_frames::collect(native_frame_ptr_t* /*out_frames*/, std::size_t /*max_frames_count*/, std::size_t /*skip*/) noexcept {
return 0;
}

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -63,7 +63,7 @@ inline _Unwind_Reason_Code unwind_callback(::_Unwind_Context* context, void* arg
}
#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 this_thread_frames::collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) noexcept {
std::size_t frames_count = 0;
if (!max_frames_count) {
return frames_count;

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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,8 +15,6 @@
#include <iosfwd>
#include <string>
#include <boost/core/explicit_operator_bool.hpp>
#include <boost/stacktrace/safe_dump_to.hpp> // boost::stacktrace::detail::native_frame_ptr_t
#include <boost/stacktrace/detail/void_ptr_cast.hpp>
@@ -47,7 +45,7 @@ public:
///
/// @b Async-Handler-Safety: Safe.
/// @throws Nothing.
BOOST_CONSTEXPR frame() BOOST_NOEXCEPT
constexpr frame() noexcept
: addr_(0)
{}
@@ -75,7 +73,7 @@ public:
///
/// @b Async-Handler-Safety: Safe.
/// @throws Nothing.
BOOST_CONSTEXPR explicit frame(native_frame_ptr_t addr) BOOST_NOEXCEPT
constexpr explicit frame(native_frame_ptr_t addr) noexcept
: addr_(addr)
{}
@@ -86,7 +84,7 @@ public:
/// @b Async-Handler-Safety: Safe.
/// @throws Nothing.
template <class T>
explicit frame(T* function_addr) BOOST_NOEXCEPT
explicit frame(T* function_addr) noexcept
: addr_(boost::stacktrace::detail::void_ptr_cast<native_frame_ptr_t>(function_addr))
{}
@@ -104,7 +102,7 @@ public:
///
/// @b Async-Handler-Safety: Safe.
/// @throws Nothing.
BOOST_CONSTEXPR native_frame_ptr_t address() const BOOST_NOEXCEPT {
constexpr native_frame_ptr_t address() const noexcept {
return addr_;
}
@@ -131,7 +129,7 @@ public:
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
BOOST_EXPLICIT_OPERATOR_BOOL()
constexpr explicit operator bool () const noexcept { return !empty(); }
/// @brief Checks that frame references NULL address.
/// @returns `true` if `this->address() == 0`
@@ -139,11 +137,7 @@ public:
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT { return !address(); }
/// @cond
BOOST_CONSTEXPR bool operator!() const BOOST_NOEXCEPT { return !address(); }
/// @endcond
constexpr bool empty() const noexcept { return !address(); }
};

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -28,9 +28,13 @@
#ifdef __CRT_UUID_DECL // for __MINGW32__
#if !defined(__MINGW32__) || \
(!defined(__clang__) && __GNUC__ < 12) || \
(defined(__clang__) && __clang_major__ < 16)
__CRT_UUID_DECL(IDebugClient,0x27fe5639,0x8407,0x4f47,0x83,0x64,0xee,0x11,0x8f,0xb0,0x8a,0xc8)
__CRT_UUID_DECL(IDebugControl,0x5182e668,0x105e,0x416e,0xad,0x92,0x24,0xef,0x80,0x04,0x24,0xba)
__CRT_UUID_DECL(IDebugSymbols,0x8c31e98c,0x983a,0x48a5,0x90,0x16,0x6f,0xe5,0xd6,0x67,0xa9,0x50)
#endif
#elif defined(DEFINE_GUID) && !defined(BOOST_MSVC)
DEFINE_GUID(IID_IDebugClient,0x27fe5639,0x8407,0x4f47,0x83,0x64,0xee,0x11,0x8f,0xb0,0x8a,0xc8);
DEFINE_GUID(IID_IDebugControl,0x5182e668,0x105e,0x416e,0xad,0x92,0x24,0xef,0x80,0x04,0x24,0xba);
@@ -44,53 +48,28 @@
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() noexcept
: holder_(0)
{}
T* operator->() const BOOST_NOEXCEPT {
T* operator->() const noexcept {
return holder_;
}
void** to_void_ptr_ptr() BOOST_NOEXCEPT {
void** to_void_ptr_ptr() noexcept {
return reinterpret_cast<void**>(&holder_);
}
bool is_inited() const BOOST_NOEXCEPT {
bool is_inited() const noexcept {
return !!holder_;
}
~com_holder() BOOST_NOEXCEPT {
~com_holder() noexcept {
if (holder_) {
holder_->Release();
}
@@ -126,13 +105,13 @@ inline void trim_right_zeroes(std::string& s) {
}
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) 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()
@@ -154,20 +133,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_)
debugging_symbols() noexcept
{
try_init_com(idebug_, com_);
try_init_com(idebug_);
}
#else
@@ -176,14 +152,13 @@ public:
# error Your compiler does not support C++11 thread_local storage. It`s impossible to build with BOOST_STACKTRACE_USE_WINDBG_CACHED.
#endif
static com_holder< ::IDebugSymbols>& get_thread_local_debug_inst() BOOST_NOEXCEPT {
static com_holder< ::IDebugSymbols>& get_thread_local_debug_inst() 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;
@@ -191,13 +166,13 @@ public:
com_holder< ::IDebugSymbols>& idebug_;
public:
debugging_symbols() BOOST_NOEXCEPT
debugging_symbols() noexcept
: idebug_( get_thread_local_debug_inst() )
{}
#endif // #ifndef BOOST_STACKTRACE_USE_WINDBG_CACHED
bool is_inited() const BOOST_NOEXCEPT {
bool is_inited() const noexcept {
return idebug_.is_inited();
}
@@ -228,9 +203,12 @@ public:
&size,
0
));
trim_right_zeroes(result);
// 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) {
@@ -256,7 +234,7 @@ public:
return result;
}
std::size_t get_line_impl(const void* addr) const BOOST_NOEXCEPT {
std::size_t get_line_impl(const void* addr) const noexcept {
ULONG result = 0;
if (!is_inited()) {
return result;

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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-2022.
// 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-2022.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -56,7 +56,7 @@ inline int libbacktrace_full_callback(void *data, uintptr_t /*pc*/, const char *
return 0;
}
inline void libbacktrace_error_callback(void* /*data*/, const char* /*msg*/, int /*errnum*/) BOOST_NOEXCEPT {
inline void libbacktrace_error_callback(void* /*data*/, const char* /*msg*/, int /*errnum*/) noexcept {
// Do nothing, just return.
}
@@ -68,7 +68,7 @@ inline void libbacktrace_error_callback(void* /*data*/, const char* /*msg*/, int
//
// Currently `backtrace_create_state` can not detect file name on Windows https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82543
// That's why we provide a `prog_location` here.
BOOST_SYMBOL_VISIBLE inline ::backtrace_state* construct_state(const program_location& prog_location) BOOST_NOEXCEPT {
BOOST_SYMBOL_VISIBLE inline ::backtrace_state* construct_state(const program_location& prog_location) noexcept {
// [dcl.inline]: A static local variable in an inline function with external linkage always refers to the same object.
// TODO: The most obvious solution:
@@ -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__) && !defined(__clang__)
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;
}
@@ -151,7 +155,7 @@ struct to_string_using_backtrace {
return true;
}
to_string_using_backtrace() BOOST_NOEXCEPT {
to_string_using_backtrace() noexcept {
state = boost::stacktrace::detail::construct_state(prog_location);
}
};

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -25,7 +25,7 @@ class location_from_symbol {
::Dl_info dli_;
public:
explicit location_from_symbol(const void* addr) BOOST_NOEXCEPT
explicit location_from_symbol(const void* addr) noexcept
: dli_()
{
if (!::dladdr(const_cast<void*>(addr), &dli_)) { // `dladdr` on Solaris accepts nonconst addresses
@@ -33,18 +33,18 @@ public:
}
}
bool empty() const BOOST_NOEXCEPT {
bool empty() const noexcept {
return !dli_.dli_fname;
}
const char* name() const BOOST_NOEXCEPT {
const char* name() const noexcept {
return dli_.dli_fname;
}
};
class program_location {
public:
const char* name() const BOOST_NOEXCEPT {
const char* name() const noexcept {
return 0;
}
};
@@ -56,7 +56,7 @@ class location_from_symbol {
char file_name_[DEFAULT_PATH_SIZE_];
public:
explicit location_from_symbol(const void* addr) BOOST_NOEXCEPT {
explicit location_from_symbol(const void* addr) noexcept {
file_name_[0] = '\0';
boost::winapi::MEMORY_BASIC_INFORMATION_ mbi;
@@ -71,11 +71,11 @@ public:
}
}
bool empty() const BOOST_NOEXCEPT {
bool empty() const noexcept {
return file_name_[0] == '\0';
}
const char* name() const BOOST_NOEXCEPT {
const char* name() const noexcept {
return file_name_;
}
};
@@ -85,7 +85,7 @@ class program_location {
char file_name_[DEFAULT_PATH_SIZE_];
public:
program_location() BOOST_NOEXCEPT {
program_location() noexcept {
file_name_[0] = '\0';
const boost::winapi::HMODULE_ handle = 0;
@@ -94,7 +94,7 @@ public:
}
}
const char* name() const BOOST_NOEXCEPT {
const char* name() const noexcept {
return file_name_[0] ? file_name_ : 0;
}
};

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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-2022.
// 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-2022.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -18,17 +18,17 @@ namespace boost { namespace stacktrace { namespace detail {
#if defined(BOOST_WINDOWS)
std::size_t dump(void* /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT {
std::size_t dump(void* /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) noexcept {
return 0;
}
#else
std::size_t dump(int /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT {
std::size_t dump(int /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) noexcept {
return 0;
}
#endif
std::size_t dump(const char* /*file*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT {
std::size_t dump(const char* /*file*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) noexcept {
return 0;
}

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -21,7 +21,7 @@
namespace boost { namespace stacktrace { namespace detail {
std::size_t dump(int fd, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT {
std::size_t dump(int fd, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept {
// We do not retry, because this function must be typically called from signal handler so it's:
// * to scary to continue in case of EINTR
// * EAGAIN or EWOULDBLOCK may occur only in case of O_NONBLOCK is set for fd,
@@ -33,7 +33,7 @@ std::size_t dump(int fd, const native_frame_ptr_t* frames, std::size_t frames_co
return frames_count;
}
std::size_t dump(const char* file, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT {
std::size_t dump(const char* file, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept {
const int fd = ::open(
file,
O_CREAT | O_WRONLY | O_TRUNC,

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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,7 +23,7 @@
namespace boost { namespace stacktrace { namespace detail {
std::size_t dump(void* /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT {
std::size_t dump(void* /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) noexcept {
#if 0 // This code potentially could cause deadlocks (according to the MSDN). Disabled
boost::winapi::DWORD_ written;
const boost::winapi::DWORD_ bytes_to_write = static_cast<boost::winapi::DWORD_>(
@@ -38,7 +38,7 @@ std::size_t dump(void* /*fd*/, const native_frame_ptr_t* /*frames*/, std::size_t
return 0;
}
std::size_t dump(const char* /*file*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) BOOST_NOEXCEPT {
std::size_t dump(const char* /*file*/, const native_frame_ptr_t* /*frames*/, std::size_t /*frames_count*/) noexcept {
#if 0 // This code causing deadlocks on some platforms. Disabled
void* const fd = boost::winapi::CreateFileA(
file,

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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,13 +12,14 @@
# pragma once
#endif
#include <boost/array.hpp>
#include <array>
#include <cstddef> // std::size_t
namespace boost { namespace stacktrace { namespace detail {
// We do not use boost::lexical_cast in this function to reduce module dependencies
inline boost::array<char, 40> to_dec_array(std::size_t value) BOOST_NOEXCEPT {
boost::array<char, 40> ret;
inline std::array<char, 40> to_dec_array(std::size_t value) noexcept {
std::array<char, 40> ret;
if (!value) {
ret[0] = '0';
ret[1] = '\0';

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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,20 +12,18 @@
# pragma once
#endif
#include <boost/array.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <array>
#include <type_traits>
namespace boost { namespace stacktrace { namespace detail {
BOOST_STATIC_CONSTEXPR char to_hex_array_bytes[] = "0123456789ABCDEF";
template <class T>
inline boost::array<char, 2 + sizeof(void*) * 2 + 1> to_hex_array(T addr) BOOST_NOEXCEPT {
boost::array<char, 2 + sizeof(void*) * 2 + 1> ret = {"0x"};
inline std::array<char, 2 + sizeof(void*) * 2 + 1> to_hex_array(T addr) noexcept {
std::array<char, 2 + sizeof(void*) * 2 + 1> ret = {"0x"};
ret.back() = '\0';
BOOST_STATIC_ASSERT_MSG(!boost::is_pointer<T>::value, "");
static_assert(!std::is_pointer<T>::value, "");
const std::size_t s = sizeof(T);
@@ -43,9 +41,9 @@ inline boost::array<char, 2 + sizeof(void*) * 2 + 1> to_hex_array(T addr) BOOST_
return ret;
}
inline boost::array<char, 2 + sizeof(void*) * 2 + 1> to_hex_array(const void* addr) BOOST_NOEXCEPT {
inline std::array<char, 2 + sizeof(void*) * 2 + 1> to_hex_array(const void* addr) noexcept {
return to_hex_array(
reinterpret_cast< boost::make_unsigned<std::ptrdiff_t>::type >(addr)
reinterpret_cast< std::make_unsigned<std::ptrdiff_t>::type >(addr)
);
}

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// Copyright Antony Polukhin, 2016-2023.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -17,7 +17,7 @@
namespace boost { namespace stacktrace { namespace detail {
// We do not use boost::lexical_cast in this function to reduce module dependencies
inline bool try_dec_convert(const char* s, std::size_t& res) BOOST_NOEXCEPT {
inline bool try_dec_convert(const char* s, std::size_t& res) noexcept {
char* end_ptr = 0;
res = std::strtoul(s, &end_ptr, 10);
return *end_ptr == '\0';

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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,7 +23,7 @@ struct to_string_using_nothing {
res = boost::stacktrace::frame(addr).name();
}
bool prepare_source_location(const void* /*addr*/) const BOOST_NOEXCEPT {
bool prepare_source_location(const void* /*addr*/) const noexcept {
return false;
}
};

View File

@@ -1,5 +1,5 @@
// Copyright 2014 Renato Tegon Forti, Antony Polukhin.
// Copyright Antony Polukhin, 2015-2022.
// Copyright Antony Polukhin, 2015-2023.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
@@ -13,8 +13,7 @@
# pragma once
#endif
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <type_traits>
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ * 100 + __GNUC_MINOR__ > 301)
# pragma GCC system_header
@@ -25,13 +24,13 @@ namespace boost { namespace stacktrace { namespace detail {
// GCC warns when reinterpret_cast between function pointer and object pointer occur.
// This functionsuppress the warnings and ensures that such casts are safe.
template <class To, class From>
To void_ptr_cast(From* v) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(
boost::is_pointer<To>::value,
To void_ptr_cast(From* v) noexcept {
static_assert(
std::is_pointer<To>::value,
"`void_ptr_cast` function must be used only for casting to or from void pointers."
);
BOOST_STATIC_ASSERT_MSG(
static_assert(
sizeof(From*) == sizeof(To),
"Pointer to function and pointer to object differ in size on your platform."
);

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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,8 +15,6 @@
#include <iosfwd>
#include <string>
#include <boost/core/explicit_operator_bool.hpp>
#include <boost/stacktrace/safe_dump_to.hpp> // boost::stacktrace::detail::native_frame_ptr_t
#include <boost/stacktrace/detail/frame_decl.hpp>
@@ -25,15 +23,15 @@
namespace boost { namespace stacktrace {
/// Comparison operators that provide platform dependant ordering and have O(1) complexity; are Async-Handler-Safe.
BOOST_CONSTEXPR inline bool operator< (const frame& lhs, const frame& rhs) BOOST_NOEXCEPT { return lhs.address() < rhs.address(); }
BOOST_CONSTEXPR inline bool operator> (const frame& lhs, const frame& rhs) BOOST_NOEXCEPT { return rhs < lhs; }
BOOST_CONSTEXPR inline bool operator<=(const frame& lhs, const frame& rhs) BOOST_NOEXCEPT { return !(lhs > rhs); }
BOOST_CONSTEXPR inline bool operator>=(const frame& lhs, const frame& rhs) BOOST_NOEXCEPT { return !(lhs < rhs); }
BOOST_CONSTEXPR inline bool operator==(const frame& lhs, const frame& rhs) BOOST_NOEXCEPT { return lhs.address() == rhs.address(); }
BOOST_CONSTEXPR inline bool operator!=(const frame& lhs, const frame& rhs) BOOST_NOEXCEPT { return !(lhs == rhs); }
constexpr inline bool operator< (const frame& lhs, const frame& rhs) noexcept { return lhs.address() < rhs.address(); }
constexpr inline bool operator> (const frame& lhs, const frame& rhs) noexcept { return rhs < lhs; }
constexpr inline bool operator<=(const frame& lhs, const frame& rhs) noexcept { return !(lhs > rhs); }
constexpr inline bool operator>=(const frame& lhs, const frame& rhs) noexcept { return !(lhs < rhs); }
constexpr inline bool operator==(const frame& lhs, const frame& rhs) noexcept { return lhs.address() == rhs.address(); }
constexpr inline bool operator!=(const frame& lhs, const frame& rhs) noexcept { return !(lhs == rhs); }
/// Fast hashing support, O(1) complexity; Async-Handler-Safe.
inline std::size_t hash_value(const frame& f) BOOST_NOEXCEPT {
inline std::size_t hash_value(const frame& f) noexcept {
return reinterpret_cast<std::size_t>(f.address());
}

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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,19 +35,19 @@ namespace detail {
enum helper{ max_frames_dump = 128 };
BOOST_STACKTRACE_FUNCTION std::size_t from_dump(const char* filename, native_frame_ptr_t* out_frames);
BOOST_STACKTRACE_FUNCTION std::size_t dump(const char* file, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT;
BOOST_STACKTRACE_FUNCTION std::size_t dump(const char* file, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept;
#if defined(BOOST_WINDOWS)
BOOST_STACKTRACE_FUNCTION std::size_t dump(void* fd, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT;
BOOST_STACKTRACE_FUNCTION std::size_t dump(void* fd, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept;
#else
// POSIX
BOOST_STACKTRACE_FUNCTION std::size_t dump(int fd, const native_frame_ptr_t* frames, std::size_t frames_count) BOOST_NOEXCEPT;
BOOST_STACKTRACE_FUNCTION std::size_t dump(int fd, const native_frame_ptr_t* frames, std::size_t frames_count) noexcept;
#endif
struct this_thread_frames { // struct is required to avoid warning about usage of inline+BOOST_NOINLINE
BOOST_NOINLINE BOOST_STACKTRACE_FUNCTION static std::size_t collect(native_frame_ptr_t* out_frames, std::size_t max_frames_count, std::size_t skip) BOOST_NOEXCEPT;
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) BOOST_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;
if (size < sizeof(native_frame_ptr_t)) {
@@ -61,7 +61,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) BOOST_NOEXCEPT {
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;
native_frame_ptr_t buffer[boost::stacktrace::detail::max_frames_dump + 1];
@@ -89,7 +89,7 @@ struct this_thread_frames { // struct is required to avoid warning about usage o
/// @param memory Preallocated buffer to store current function call sequence into.
///
/// @param size Size of the preallocated buffer.
BOOST_FORCEINLINE std::size_t safe_dump_to(void* memory, std::size_t size) BOOST_NOEXCEPT {
BOOST_FORCEINLINE std::size_t safe_dump_to(void* memory, std::size_t size) noexcept {
return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(memory, size, 0);
}
@@ -106,7 +106,7 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(void* memory, std::size_t size) BOOST
/// @param memory Preallocated buffer to store current function call sequence into.
///
/// @param size Size of the preallocated buffer.
BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, void* memory, std::size_t size) BOOST_NOEXCEPT {
BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, void* memory, std::size_t size) noexcept {
return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(memory, size, skip);
}
@@ -120,7 +120,7 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, void* memory, std::
/// @returns Stored call sequence depth including terminating zero frame.
///
/// @param file File to store current function call sequence.
BOOST_FORCEINLINE std::size_t safe_dump_to(const char* file) BOOST_NOEXCEPT {
BOOST_FORCEINLINE std::size_t safe_dump_to(const char* file) noexcept {
return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(file, 0, boost::stacktrace::detail::max_frames_dump);
}
@@ -137,7 +137,7 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(const char* file) BOOST_NOEXCEPT {
/// @param max_depth Max call sequence depth to collect.
///
/// @param file File to store current function call sequence.
BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, const char* file) BOOST_NOEXCEPT {
BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, const char* file) noexcept {
return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(file, skip, max_depth);
}
@@ -152,7 +152,7 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_dep
/// @returns Stored call sequence depth including terminating zero frame.
///
/// @param file File to store current function call sequence.
BOOST_FORCEINLINE std::size_t safe_dump_to(platform_specific_descriptor fd) BOOST_NOEXCEPT;
BOOST_FORCEINLINE std::size_t safe_dump_to(platform_specific_descriptor fd) noexcept;
/// @brief Writes into the provided file descriptor the current function call sequence if such operation is async signal safe.
///
@@ -167,26 +167,26 @@ BOOST_FORCEINLINE std::size_t safe_dump_to(platform_specific_descriptor fd) BOOS
/// @param max_depth Max call sequence depth to collect.
///
/// @param file File to store current function call sequence.
BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, platform_specific_descriptor fd) BOOST_NOEXCEPT;
BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, platform_specific_descriptor fd) noexcept;
#elif defined(BOOST_WINDOWS)
BOOST_FORCEINLINE std::size_t safe_dump_to(void* fd) BOOST_NOEXCEPT {
BOOST_FORCEINLINE std::size_t safe_dump_to(void* fd) noexcept {
return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump);
}
BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, void* fd) BOOST_NOEXCEPT {
BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, void* fd) noexcept {
return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, skip, max_depth);
}
#else
// POSIX
BOOST_FORCEINLINE std::size_t safe_dump_to(int fd) BOOST_NOEXCEPT {
BOOST_FORCEINLINE std::size_t safe_dump_to(int fd) noexcept {
return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, 0, boost::stacktrace::detail::max_frames_dump);
}
BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, int fd) BOOST_NOEXCEPT {
BOOST_FORCEINLINE std::size_t safe_dump_to(std::size_t skip, std::size_t max_depth, int fd) noexcept {
return boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl(fd, skip, max_depth);
}

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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,7 +12,6 @@
# pragma once
#endif
#include <boost/core/explicit_operator_bool.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/container_hash/hash_fwd.hpp>
@@ -27,6 +26,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)
@@ -59,7 +59,7 @@ class basic_stacktrace {
}
}
static std::size_t frames_count_from_buffer_size(std::size_t buffer_size) BOOST_NOEXCEPT {
static std::size_t frames_count_from_buffer_size(std::size_t buffer_size) noexcept {
const std::size_t ret = (buffer_size > sizeof(native_frame_ptr_t) ? buffer_size / sizeof(native_frame_ptr_t) : 0);
return (ret > 1024 ? 1024 : ret); // Dealing with suspiciously big sizes
}
@@ -122,7 +122,7 @@ public:
/// @b Complexity: O(N) where N is call sequence length, O(1) if BOOST_STACKTRACE_USE_NOOP is defined.
///
/// @b Async-Handler-Safety: Safe if Allocator construction, copying, Allocator::allocate and Allocator::deallocate are async signal safe.
BOOST_FORCEINLINE basic_stacktrace() BOOST_NOEXCEPT
BOOST_FORCEINLINE basic_stacktrace() noexcept
: impl_()
{
init(0 , static_cast<std::size_t>(-1));
@@ -134,8 +134,8 @@ 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.
BOOST_FORCEINLINE explicit basic_stacktrace(const allocator_type& a) BOOST_NOEXCEPT
/// @param a Allocator that would be passed to underlying storage.
BOOST_FORCEINLINE explicit basic_stacktrace(const allocator_type& a) noexcept
: impl_(a)
{
init(0 , static_cast<std::size_t>(-1));
@@ -151,11 +151,11 @@ 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`.
BOOST_FORCEINLINE basic_stacktrace(std::size_t skip, std::size_t max_depth, const allocator_type& a = allocator_type()) BOOST_NOEXCEPT
BOOST_FORCEINLINE basic_stacktrace(std::size_t skip, std::size_t max_depth, const allocator_type& a = allocator_type()) noexcept
: impl_(a)
{
init(skip , max_depth);
@@ -180,14 +180,14 @@ public:
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe if Allocator::deallocate is async signal safe.
~basic_stacktrace() BOOST_NOEXCEPT = default;
~basic_stacktrace() noexcept = default;
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe if Allocator construction and copying are async signal safe.
basic_stacktrace(basic_stacktrace&& st) BOOST_NOEXCEPT
basic_stacktrace(basic_stacktrace&& st) noexcept
: impl_(std::move(st.impl_))
{}
@@ -196,9 +196,9 @@ public:
/// @b Async-Handler-Safety: Safe if Allocator construction and copying are async signal safe.
basic_stacktrace& operator=(basic_stacktrace&& st)
#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS
BOOST_NOEXCEPT_IF(( std::is_nothrow_move_assignable< std::vector<boost::stacktrace::frame, Allocator> >::value ))
noexcept(( std::is_nothrow_move_assignable< std::vector<boost::stacktrace::frame, Allocator> >::value ))
#else
BOOST_NOEXCEPT
noexcept
#endif
{
impl_ = std::move(st.impl_);
@@ -211,7 +211,7 @@ public:
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
size_type size() const BOOST_NOEXCEPT {
size_type size() const noexcept {
return impl_.size();
}
@@ -223,43 +223,43 @@ public:
/// @b Complexity: O(1).
///
/// @b Async-Handler-Safety: Safe.
const_reference operator[](std::size_t frame_no) const BOOST_NOEXCEPT {
const_reference operator[](std::size_t frame_no) const noexcept {
return impl_[frame_no];
}
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
const_iterator begin() const BOOST_NOEXCEPT { return impl_.begin(); }
const_iterator begin() const noexcept { return impl_.begin(); }
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
const_iterator cbegin() const BOOST_NOEXCEPT { return impl_.begin(); }
const_iterator cbegin() const noexcept { return impl_.begin(); }
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
const_iterator end() const BOOST_NOEXCEPT { return impl_.end(); }
const_iterator end() const noexcept { return impl_.end(); }
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
const_iterator cend() const BOOST_NOEXCEPT { return impl_.end(); }
const_iterator cend() const noexcept { return impl_.end(); }
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return impl_.rbegin(); }
const_reverse_iterator rbegin() const noexcept { return impl_.rbegin(); }
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return impl_.rbegin(); }
const_reverse_iterator crbegin() const noexcept { return impl_.rbegin(); }
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
const_reverse_iterator rend() const BOOST_NOEXCEPT { return impl_.rend(); }
const_reverse_iterator rend() const noexcept { return impl_.rend(); }
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
const_reverse_iterator crend() const BOOST_NOEXCEPT { return impl_.rend(); }
const_reverse_iterator crend() const noexcept { return impl_.rend(); }
/// @brief Allows to check that stack trace capturing was successful.
@@ -268,7 +268,7 @@ public:
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
constexpr explicit operator bool () const noexcept { return !empty(); }
/// @brief Allows to check that stack trace failed.
/// @returns `true` if `this->size() == 0`
@@ -276,13 +276,9 @@ public:
/// @b Complexity: O(1)
///
/// @b Async-Handler-Safety: Safe.
bool empty() const BOOST_NOEXCEPT { return !size(); }
bool empty() const noexcept { return !size(); }
/// @cond
bool operator!() const BOOST_NOEXCEPT { return !size(); }
/// @endcond
const std::vector<boost::stacktrace::frame, Allocator>& as_vector() const BOOST_NOEXCEPT {
const std::vector<boost::stacktrace::frame, Allocator>& as_vector() const noexcept {
return impl_;
}
@@ -319,7 +315,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
///
@@ -352,7 +348,7 @@ public:
///
/// @b Async-Handler-Safety: Safe.
template <class Allocator1, class Allocator2>
bool operator< (const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) BOOST_NOEXCEPT {
bool operator< (const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) noexcept {
return lhs.size() < rhs.size() || (lhs.size() == rhs.size() && lhs.as_vector() < rhs.as_vector());
}
@@ -362,35 +358,35 @@ bool operator< (const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<
///
/// @b Async-Handler-Safety: Safe.
template <class Allocator1, class Allocator2>
bool operator==(const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) BOOST_NOEXCEPT {
bool operator==(const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) noexcept {
return lhs.as_vector() == rhs.as_vector();
}
/// Comparison operators that provide platform dependant ordering and have amortized O(1) complexity; O(size()) worst case complexity; are Async-Handler-Safe.
template <class Allocator1, class Allocator2>
bool operator> (const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) BOOST_NOEXCEPT {
bool operator> (const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) noexcept {
return rhs < lhs;
}
template <class Allocator1, class Allocator2>
bool operator<=(const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) BOOST_NOEXCEPT {
bool operator<=(const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) noexcept {
return !(lhs > rhs);
}
template <class Allocator1, class Allocator2>
bool operator>=(const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) BOOST_NOEXCEPT {
bool operator>=(const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) noexcept {
return !(lhs < rhs);
}
template <class Allocator1, class Allocator2>
bool operator!=(const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) BOOST_NOEXCEPT {
bool operator!=(const basic_stacktrace<Allocator1>& lhs, const basic_stacktrace<Allocator2>& rhs) noexcept {
return !(lhs == rhs);
}
/// Fast hashing support, O(st.size()) complexity; Async-Handler-Safe.
template <class Allocator>
std::size_t hash_value(const basic_stacktrace<Allocator>& st) BOOST_NOEXCEPT {
std::size_t hash_value(const basic_stacktrace<Allocator>& st) noexcept {
return boost::hash_range(st.as_vector().begin(), st.as_vector().end());
}

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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,16 +1,18 @@
<!DOCTYPE html>
<!--
Copyright (c) Antony Polukhin, 2014-2022
Copyright (c) Antony Polukhin, 2014-2023
antoshkka at gmail dot com
Distributed under the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt
or copy at http://boost.org/LICENSE_1_0.txt)
boost-no-inspect
-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; url=https://www.boost.org/doc/libs/master/doc/html/stacktrace.html">
<meta http-equiv="refresh" content="0; url=../../doc/html/stacktrace.html">
<title>Boost.Stacktrace</title>
<style>
body {
@@ -26,10 +28,10 @@
<body>
<p>
Automatic redirection failed, please go to
<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>
<a href="../../doc/html/stacktrace.html">../../doc/html/stacktrace.html</a>
</p>
<p>
&copy; Antony Polukhin, 2014-2022
&copy; Antony Polukhin, 2014-2023
</p>
</body>
</html>

View File

@@ -11,5 +11,6 @@
"std": [ "c++23" ],
"category": [
"System", "Correctness"
]
],
"cxxstd": "11"
}

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2016-2021, Antony Polukhin.
# Copyright (C) 2016-2023, 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
@@ -24,6 +24,7 @@ lib backtrace
project
: requirements
[ requires cxx11_rvalue_references ]
<toolset>msvc:<asynch-exceptions>on
<toolset>intel:<cxxflags>-wd2196
<target-os>linux:<linkflags>-lpthread
@@ -81,6 +82,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 ]
@@ -88,6 +90,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 ]
@@ -96,10 +107,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 ]
@@ -110,15 +133,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
@@ -170,23 +184,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 ]
;

View File

@@ -2,23 +2,26 @@
# 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-2022.
# Copyright Antony Polukhin, 2016-2023.
#
# 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 #5
# File revision #6
init:
- set BRANCH_TO_TEST=%APPVEYOR_REPO_BRANCH% # Change to branch you wish to test. Use %APPVEYOR_REPO_BRANCH% for current branch.
- set BOOST_REMOVE=stacktrace # Remove this folder from lib from full clone of Boost. If you are testing `any` repo, write here `any`.
# boost-local/libs/ folder to put this library into. This may be useful, if you're for example running Travis
# from `Boost.DLL` repo while Boost already has `dll` and with to replace `dll` with content of`Boost.DLL`.
#
# Otherwise just leave the default value - set BOOST_LIBS_FOLDER=%APPVEYOR_PROJECT_NAME%
- set BOOST_LIBS_FOLDER=%APPVEYOR_PROJECT_NAME%
###############################################################################################################
# From this point and below code is same for all the Boost libs
###############################################################################################################
version: 1.64.{build}-{branch}
version: 1.84.{build}-{branch}
# branches to build
branches:
@@ -27,32 +30,56 @@ branches:
skip_tags: true
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1 # ,clang-win
CXXSTD: 14,17
ADDRMD: 64
#- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# ADDPATH: C:\cygwin\bin;
# TOOLSET: gcc
# CXXSTD: 03,11,14,1z
#- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# ADDPATH: C:\cygwin64\bin;
# TOOLSET: gcc
# CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
#- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# ADDPATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;
# TOOLSET: gcc
# CXXSTD: 03,11,14,1z
before_build:
- set PATH=%PATH%;C:\\MinGW\\bin
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- echo "Testing %APPVEYOR_PROJECT_NAME%"
# Cloning Boost libraries (fast nondeep cloning)
- set BOOST=C:/boost-local
- git init %BOOST%
- git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git %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 --init --merge --jobs 16
- git remote set-branches --add origin %BRANCH_TO_TEST%
#- git pull --recurse-submodules # Updaes submodules to most recent version. Not required
- rm -rf %BOOST%/libs/%BOOST_REMOVE%
- mv %APPVEYOR_BUILD_FOLDER% %BOOST%/libs/%APPVEYOR_PROJECT_NAME%
- git submodule update --init --depth 10 tools/build tools/boostdep libs/filesystem libs/interprocess
- 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%
build_script:
- call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
- bootstrap.bat
- cmd /c bootstrap
- b2.exe headers
- cd %BOOST%/libs/%APPVEYOR_PROJECT_NAME%/test
- cd %BOOST%/libs/%BOOST_LIBS_FOLDER%/test
after_build:
before_test:
test_script:
- ..\..\..\b2.exe address-model=32 architecture=x86 toolset=msvc,gcc cxxflags="-DBOOST_TRAVISCI_BUILD" -sBOOST_BUILD_PATH=.
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- echo "Running command ..\..\..\b2 -j3 toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release"
- ..\..\..\b2.exe -j3 toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release cxxflags="-DBOOST_TRAVISCI_BUILD"
after_test:
on_success:

View File

@@ -1,4 +1,4 @@
// Copyright Antony Polukhin, 2016-2022.
// 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-2022.
// 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-2022.
// 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-2022.
// 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-2022.
// 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-2022.
// 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();
}