mirror of
https://github.com/boostorg/stacktrace.git
synced 2026-02-22 03:32:27 +00:00
Output more information in stacktraces (instruction offsets and function addressees) when apropriate
This commit is contained in:
@@ -150,13 +150,8 @@ std::basic_ostream<CharT, TraitsT>& operator<<(std::basic_ostream<CharT, TraitsT
|
||||
os.width(2);
|
||||
os << i;
|
||||
os.width(w);
|
||||
const std::string f = bt[i];
|
||||
os << "# ";
|
||||
if (f.empty()) {
|
||||
os << "??";
|
||||
} else {
|
||||
os << f;
|
||||
}
|
||||
os << bt[i];
|
||||
os << '\n';
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <cstring>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/stacktrace/detail/to_hex_array.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
@@ -74,6 +76,9 @@ struct backtrace_holder {
|
||||
res.resize( std::strlen(res.data()) ); // Note: here res is \0 terminated, but size() not equal to strlen
|
||||
}
|
||||
|
||||
res += " +";
|
||||
res += to_hex_array(offp).data();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#endif
|
||||
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <boost/stacktrace/detail/to_hex_array.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <execinfo.h>
|
||||
@@ -34,18 +36,18 @@ struct backtrace_holder {
|
||||
return res;
|
||||
}
|
||||
|
||||
Dl_info dli;
|
||||
if (!dladdr(buffer[frame], &dli)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (dli.dli_sname) {
|
||||
Dl_info dli;
|
||||
if (!!dladdr(buffer[frame], &dli) && dli.dli_sname) {
|
||||
boost::core::scoped_demangled_name demangled(dli.dli_sname);
|
||||
if (demangled.get()) {
|
||||
res = demangled.get();
|
||||
} else {
|
||||
res = dli.dli_sname;
|
||||
}
|
||||
} else {
|
||||
res = "?? at ";
|
||||
res += to_hex_array(buffer[frame]).data();
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/stacktrace/detail/to_hex_array.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#include <windows.h>
|
||||
#include "DbgHelp.h"
|
||||
#include <WinBase.h>
|
||||
@@ -76,6 +79,9 @@ struct backtrace_holder {
|
||||
);
|
||||
if (sym_res) {
|
||||
res = s.symbol.Name;
|
||||
} else {
|
||||
res = "?? at ";
|
||||
res += to_hex_array(buffer[frame]).data();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
|
||||
namespace boost { namespace stacktrace { namespace detail {
|
||||
|
||||
struct backtrace_holder;
|
||||
@@ -39,33 +36,6 @@ inline boost::stacktrace::detail::backtrace_holder& construct_bt_and_return(back
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
BOOST_STATIC_CONSTEXPR char to_hex_array[] = "0123456789ABCDEF";
|
||||
|
||||
template <class T>
|
||||
inline boost::array<char, 2 + sizeof(void*) * 2 + 1> to_hex(T addr) BOOST_NOEXCEPT {
|
||||
boost::array<char, 2 + sizeof(void*) * 2 + 1> ret = {"0x"};
|
||||
ret.back() = '\0';
|
||||
BOOST_STATIC_ASSERT_MSG(!boost::is_pointer<T>::value, "");
|
||||
|
||||
const std::size_t s = (
|
||||
(addr >> (sizeof(addr) / 2 * 8)) ? sizeof(addr) : sizeof(addr) / 2
|
||||
);
|
||||
|
||||
char* out = ret.data() + s * 2 + 1;
|
||||
|
||||
for (std::size_t i = 0; i < s; ++i) {
|
||||
const unsigned char tmp_addr = (addr & 0xFFu);
|
||||
*out = to_hex_array[tmp_addr & 0xF];
|
||||
-- out;
|
||||
*out = to_hex_array[tmp_addr >> 4];
|
||||
-- out;
|
||||
addr >>= 8;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}*/
|
||||
|
||||
}}} // namespace boost::stacktrace::detail
|
||||
|
||||
#endif // BOOST_STACKTRACE_DETAIL_STACKTRACE_HELPERS_HPP
|
||||
|
||||
@@ -21,6 +21,9 @@ namespace boost { namespace stacktrace {
|
||||
stacktrace::stacktrace() BOOST_NOEXCEPT {
|
||||
boost::stacktrace::detail::backtrace_holder& bt = boost::stacktrace::detail::construct_bt_and_return(impl_);
|
||||
bt.frames_count = ::backtrace(bt.buffer, boost::stacktrace::detail::backtrace_holder::max_size);
|
||||
if (bt.buffer[bt.frames_count] == 0) {
|
||||
-- bt.frames_count;
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace boost::stacktrace
|
||||
|
||||
66
include/boost/stacktrace/detail/to_hex_array.hpp
Normal file
66
include/boost/stacktrace/detail/to_hex_array.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright Antony Polukhin, 2016.
|
||||
//
|
||||
// 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_STACKTRACE_TO_HEX_ARRAY_HPP
|
||||
#define BOOST_STACKTRACE_DETAIL_STACKTRACE_TO_HEX_ARRAY_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
|
||||
namespace boost { namespace stacktrace { namespace detail {
|
||||
|
||||
BOOST_STATIC_CONSTEXPR char to_hex_array_bytes[] = "0123456789ABCDEF";
|
||||
|
||||
template <class T>
|
||||
inline bool can_be_safely_trimmed_by(T addr, std::size_t part) BOOST_NOEXCEPT {
|
||||
return !(addr >> (sizeof(T) / part * 8));
|
||||
}
|
||||
|
||||
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"};
|
||||
ret.back() = '\0';
|
||||
BOOST_STATIC_ASSERT_MSG(!boost::is_pointer<T>::value, "");
|
||||
|
||||
const std::size_t s = (
|
||||
can_be_safely_trimmed_by(addr, 2)
|
||||
? (can_be_safely_trimmed_by(addr, 4)
|
||||
? (can_be_safely_trimmed_by(addr, 8)
|
||||
? sizeof(addr) / 8
|
||||
: sizeof(addr) / 4)
|
||||
: sizeof(addr) / 2)
|
||||
: sizeof(addr)
|
||||
);
|
||||
|
||||
char* out = ret.data() + s * 2 + 1;
|
||||
|
||||
for (std::size_t i = 0; i < s; ++i) {
|
||||
const unsigned char tmp_addr = (addr & 0xFFu);
|
||||
*out = to_hex_array_bytes[tmp_addr & 0xF];
|
||||
-- out;
|
||||
*out = to_hex_array_bytes[tmp_addr >> 4];
|
||||
-- out;
|
||||
addr >>= 8;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline boost::array<char, 2 + sizeof(void*) * 2 + 1> to_hex_array(void* addr) BOOST_NOEXCEPT {
|
||||
return to_hex_array(
|
||||
reinterpret_cast<std::size_t>(addr)
|
||||
);
|
||||
}
|
||||
|
||||
}}} // namespace boost::stacktrace::detail
|
||||
|
||||
#endif // BOOST_STACKTRACE_DETAIL_STACKTRACE_TO_HEX_ARRAY_HPP
|
||||
Reference in New Issue
Block a user