Output more information in stacktraces (instruction offsets and function addressees) when apropriate

This commit is contained in:
Antony Polukhin
2016-10-12 20:23:54 +03:00
parent b75dfd361c
commit 2440061676
8 changed files with 90 additions and 42 deletions

View File

@@ -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';
}

View File

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

View File

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

View File

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

View File

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

View File

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

View 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