Compare commits

...

18 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
27 changed files with 353 additions and 180 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

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-2022, 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
;

View File

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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);
@@ -49,23 +53,23 @@ class com_holder: boost::noncopyable {
T* holder_;
public:
com_holder() 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();
}
@@ -101,7 +105,7 @@ inline void trim_right_zeroes(std::string& s) {
}
class debugging_symbols: boost::noncopyable {
static void try_init_com(com_holder< ::IDebugSymbols>& idebug) BOOST_NOEXCEPT {
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;
@@ -137,7 +141,7 @@ class debugging_symbols: boost::noncopyable {
com_holder< ::IDebugSymbols> idebug_;
public:
debugging_symbols() BOOST_NOEXCEPT
debugging_symbols() noexcept
{
try_init_com(idebug_);
}
@@ -148,7 +152,7 @@ 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 com_holder< ::IDebugSymbols> idebug;
@@ -162,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();
}
@@ -230,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

@@ -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:
@@ -155,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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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>
@@ -60,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
}
@@ -123,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));
@@ -136,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 storage.
BOOST_FORCEINLINE explicit basic_stacktrace(const allocator_type& a) BOOST_NOEXCEPT
BOOST_FORCEINLINE explicit basic_stacktrace(const allocator_type& a) noexcept
: impl_(a)
{
init(0 , static_cast<std::size_t>(-1));
@@ -156,7 +155,7 @@ public:
///
/// @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);
@@ -181,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_))
{}
@@ -197,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_);
@@ -212,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();
}
@@ -224,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.
@@ -269,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`
@@ -277,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_;
}
@@ -353,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());
}
@@ -363,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

@@ -6,11 +6,13 @@
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,7 +28,7 @@
<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-2023

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

View File

@@ -8,17 +8,20 @@
# 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: