Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt

cmake_minimum_required(VERSION 3.8...4.20)
cmake_minimum_required(VERSION 3.8...4.4)

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

function(stacktrace_add_module name import_std)
target_sources(${name}
PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS "${CMAKE_CURRENT_LIST_DIR}/modules"
FILES "${CMAKE_CURRENT_LIST_DIR}/modules/${name}.cppm"
BASE_DIRS modules
FILES "modules/${name}.cppm"
)
target_compile_definitions(${name} PUBLIC BOOST_USE_MODULES)

if(${import_std})
target_compile_features(${name} PUBLIC cxx_std_23)
target_compile_definitions(${name} PRIVATE BOOST_STACKTRACE_USE_STD_MODULE)
target_compile_definitions(${name} PUBLIC BOOST_STACKTRACE_USE_STD_MODULE)
else()
target_compile_features(${name} PUBLIC cxx_std_20)
endif()
Expand Down
21 changes: 11 additions & 10 deletions include/boost/stacktrace/detail/addr2line_impls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
# pragma once
#endif

#include <cstring> // std::strchr
#include <cstdio> // fclose, fdopen, dup2

#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT)
#include <boost/core/demangle.hpp>

#include <cstdio>
#include <cstring>

#include <sys/types.h>
#include <sys/wait.h>
Expand Down Expand Up @@ -163,11 +164,11 @@ inline std::string addr2line(const char* flag, const void* addr) {
}

inline std::string source_location(const void* addr, bool position_independent) {
uintptr_t addr_base = 0;
std::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);
const void* offset = reinterpret_cast<void*>(reinterpret_cast<std::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 "";
Expand Down Expand Up @@ -210,11 +211,11 @@ template <class Base> class to_string_impl_base;
typedef to_string_impl_base<to_string_using_addr2line> to_string_impl;

inline std::string name(const void* addr, bool position_independent) {
uintptr_t addr_base = 0;
std::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);
const void* offset = reinterpret_cast<void*>(reinterpret_cast<std::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());
Expand All @@ -237,11 +238,11 @@ inline std::string name_impl(const void* addr) {

inline std::string source_file(const void* addr, bool position_independent) {
std::string res;
uintptr_t addr_base = 0;
std::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);
const void* offset = reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(addr) - addr_base);
res = boost::stacktrace::detail::addr2line("-e", offset);
res = res.substr(0, res.find_last_of(':'));
if (res == "??") {
Expand All @@ -253,11 +254,11 @@ inline std::string source_file(const void* addr, bool position_independent) {

inline std::size_t source_line(const void* addr, bool position_independent) {
std::size_t line_num = 0;
uintptr_t addr_base = 0;
std::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);
const void* offset = reinterpret_cast<void*>(reinterpret_cast<std::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) {
Expand Down
21 changes: 11 additions & 10 deletions include/boost/stacktrace/detail/addr_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,26 @@
#if !defined(BOOST_STACKTRACE_INTERFACE_UNIT) && !defined(BOOST_STACKTRACE_USE_STD_MODULE)
#include <fstream>
#include <sstream>
#include <cstdint>
#include <cstdlib>
#include <cstdint> // std::uintptr_t
#include <stdexcept>
#include <string>
#endif // !defined(BOOST_STACKTRACE_INTERFACE_UNIT) && !defined(BOOST_STACKTRACE_USE_STD_MODULE)

namespace boost { namespace stacktrace { namespace detail {

struct mapping_entry_t {
uintptr_t start = 0;
uintptr_t end = 0;
uintptr_t offset_from_base = 0;
std::uintptr_t start = 0;
std::uintptr_t end = 0;
std::uintptr_t offset_from_base = 0;

inline bool contains_addr(const void* addr) const {
uintptr_t addr_uint = reinterpret_cast<uintptr_t>(addr);
std::uintptr_t addr_uint = reinterpret_cast<std::uintptr_t>(addr);
return addr_uint >= start && addr_uint < end;
}
};

inline uintptr_t hex_str_to_int(const std::string& str) {
uintptr_t out;
inline std::uintptr_t hex_str_to_int(const std::string& str) {
std::uintptr_t out;
std::stringstream ss;
ss << std::hex << str;
ss >> out;
Expand Down Expand Up @@ -70,12 +71,12 @@ inline mapping_entry_t parse_proc_maps_line(const std::string& line) {
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) {
} catch(const std::invalid_argument& e) {
return mapping_entry_t{};
}
}

inline uintptr_t get_own_proc_addr_base(const void* addr) {
inline std::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);
Expand Down
8 changes: 4 additions & 4 deletions include/boost/stacktrace/detail/frame_msvc.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ public:
nullptr,
&base
));

if (res) {
name[0] = '\0';
size = 0;
Expand Down Expand Up @@ -303,7 +303,7 @@ public:
}
else if (res && size > 1) {
module_name->assign(name, size - 1);
}
}
}
}

Expand Down Expand Up @@ -402,8 +402,8 @@ public:
res += to_hex_array(addr).data();
#else
// Get own base address
const uintptr_t base_addr = get_own_proc_addr_base(addr);
res += to_hex_array(reinterpret_cast<uintptr_t>(addr) - base_addr).data();
const std::uintptr_t base_addr = get_own_proc_addr_base(addr);
res += to_hex_array(reinterpret_cast<std::uintptr_t>(addr) - base_addr).data();
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion include/boost/stacktrace/detail/frame_unwind.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public:
Base::res = to_hex_array(addr).data();
#else
const auto addr_base = boost::stacktrace::detail::get_own_proc_addr_base(addr);
Base::res = to_hex_array(reinterpret_cast<uintptr_t>(addr) - addr_base).data();
Base::res = to_hex_array(reinterpret_cast<std::uintptr_t>(addr) - addr_base).data();
#endif
}

Expand Down
20 changes: 10 additions & 10 deletions include/boost/stacktrace/detail/libbacktrace_impls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ struct pc_data {
std::size_t line;
};

inline void libbacktrace_syminfo_callback(void *data, uintptr_t /*pc*/, const char *symname, uintptr_t /*symval*/, uintptr_t /*symsize*/) {
inline void libbacktrace_syminfo_callback(void *data, std::uintptr_t /*pc*/, const char *symname, std::uintptr_t /*symval*/, std::uintptr_t /*symsize*/) {
pc_data& d = *static_cast<pc_data*>(data);
if (d.function && symname) {
*d.function = symname;
}
}

// Old versions of libbacktrace have different signature for the callback
inline void libbacktrace_syminfo_callback(void *data, uintptr_t pc, const char *symname, uintptr_t symval) {
inline void libbacktrace_syminfo_callback(void *data, std::uintptr_t pc, const char *symname, std::uintptr_t symval) {
boost::stacktrace::detail::libbacktrace_syminfo_callback(data, pc, symname, symval, 0);
}

inline int libbacktrace_full_callback(void *data, uintptr_t /*pc*/, const char *filename, int lineno, const char *function) {
inline int libbacktrace_full_callback(void *data, std::uintptr_t /*pc*/, const char *filename, int lineno, const char *function) {
pc_data& d = *static_cast<pc_data*>(data);
if (d.filename && filename) {
*d.filename = filename;
Expand Down Expand Up @@ -129,15 +129,15 @@ struct to_string_using_backtrace {
if (state) {
::backtrace_pcinfo(
state,
reinterpret_cast<uintptr_t>(addr),
reinterpret_cast<std::uintptr_t>(addr),
boost::stacktrace::detail::libbacktrace_full_callback,
boost::stacktrace::detail::libbacktrace_error_callback,
&data
)
)
||
::backtrace_syminfo(
state,
reinterpret_cast<uintptr_t>(addr),
reinterpret_cast<std::uintptr_t>(addr),
boost::stacktrace::detail::libbacktrace_syminfo_callback,
boost::stacktrace::detail::libbacktrace_error_callback,
&data
Expand Down Expand Up @@ -176,15 +176,15 @@ inline std::string name_impl(const void* addr) {
if (state) {
::backtrace_pcinfo(
state,
reinterpret_cast<uintptr_t>(addr),
reinterpret_cast<std::uintptr_t>(addr),
boost::stacktrace::detail::libbacktrace_full_callback,
boost::stacktrace::detail::libbacktrace_error_callback,
&data
)
||
::backtrace_syminfo(
state,
reinterpret_cast<uintptr_t>(addr),
reinterpret_cast<std::uintptr_t>(addr),
boost::stacktrace::detail::libbacktrace_syminfo_callback,
boost::stacktrace::detail::libbacktrace_error_callback,
&data
Expand Down Expand Up @@ -213,7 +213,7 @@ std::string frame::source_file() const {
if (state) {
::backtrace_pcinfo(
state,
reinterpret_cast<uintptr_t>(addr_),
reinterpret_cast<std::uintptr_t>(addr_),
boost::stacktrace::detail::libbacktrace_full_callback,
boost::stacktrace::detail::libbacktrace_error_callback,
&data
Expand All @@ -235,7 +235,7 @@ std::size_t frame::source_line() const {
if (state) {
::backtrace_pcinfo(
state,
reinterpret_cast<uintptr_t>(addr_),
reinterpret_cast<std::uintptr_t>(addr_),
boost::stacktrace::detail::libbacktrace_full_callback,
boost::stacktrace::detail::libbacktrace_error_callback,
&data
Expand Down
8 changes: 6 additions & 2 deletions modules/boost_stacktrace_dump.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ module;
#include <boost/predef.h>

#if !defined(BOOST_STACKTRACE_USE_STD_MODULE)
#include <stdio.h>
#include <cstdio>
#include <cstdint> // std::uintptr_t
#endif

#include <fcntl.h>
#include <unwind.h>
#include <sys/stat.h>

#if !defined(BOOST_WINDOWS)
# include <unwind.h>
#endif

#define BOOST_STACKTRACE_INTERFACE_UNIT
#define BOOST_STACKTRACE_LINK

Expand Down
10 changes: 5 additions & 5 deletions test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void test_nested(bool print = true) {

BOOST_TEST(ss1.str().find(" 1# ") != std::string::npos);
BOOST_TEST(ss2.str().find(" 1# ") != std::string::npos);

BOOST_TEST(ss1.str().find(" in ") != std::string::npos);
BOOST_TEST(ss2.str().find(" in ") != std::string::npos);

Expand Down Expand Up @@ -212,7 +212,7 @@ void test_frame() {
BOOST_TEST(fv);
if (i > 1 && i < min_size - 3) { // Begin ...and end of the trace may match, skipping
BOOST_TEST(st[i] != fv);

#if !(defined(BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL) && defined(BOOST_MSVC))
// MSVC can not get function name withhout debug symbols even if it is exported
BOOST_TEST(st[i].name() != fv.name());
Expand Down Expand Up @@ -276,15 +276,15 @@ std::size_t get_file_size(const char* file_name) {
return static_cast<std::size_t>(file_size);
}

uintptr_t get_address_from_frame(const std::string& frame) {
std::uintptr_t get_address_from_frame(const std::string& frame) {
std::size_t address = 0;
std::string hex_address;
std::size_t pos = frame.find("0x");

if (pos != std::string::npos) {
// Extract the hex address substring
hex_address = frame.substr(pos + 2); // Skip "0x"

// Convert hex string to std::size_t
std::stringstream ss;
ss << std::hex << hex_address;
Expand All @@ -295,7 +295,7 @@ uintptr_t get_address_from_frame(const std::string& frame) {
}

void test_relative_virtual_address(const char* file_path)
{
{
const auto frame = to_string(boost::stacktrace::stacktrace(0, 1).as_vector().front());

// Skip the test if the frame does not contain an address
Expand Down