mirror of
https://github.com/boostorg/stacktrace.git
synced 2026-02-22 03:32:27 +00:00
Added support for hashing
This commit is contained in:
@@ -86,6 +86,8 @@ class stacktrace {
|
||||
boost::stacktrace::detail::backtrace_holder impl_;
|
||||
#endif
|
||||
|
||||
std::size_t hash_code_;
|
||||
|
||||
public:
|
||||
/// @brief Stores the current function call sequence inside the class.
|
||||
///
|
||||
@@ -136,6 +138,13 @@ public:
|
||||
///
|
||||
/// @b Complexity: Amortized O(1); worst case O(size())
|
||||
BOOST_STACKTRACE_FUNCTION bool operator==(const stacktrace& rhs) const BOOST_NOEXCEPT;
|
||||
|
||||
/// @brief Returns hashed code of the stacktrace.
|
||||
///
|
||||
/// @b Complexity: O(1)
|
||||
std::size_t hash_code() const BOOST_NOEXCEPT {
|
||||
return hash_code_;
|
||||
}
|
||||
};
|
||||
|
||||
/// Additional comparison operators for stacktraces that have amortized O(1) complexity.
|
||||
@@ -144,6 +153,11 @@ inline bool operator<=(const stacktrace& lhs, const stacktrace& rhs) BOOST_NOEXC
|
||||
inline bool operator>=(const stacktrace& lhs, const stacktrace& rhs) BOOST_NOEXCEPT { return !(lhs < rhs); }
|
||||
inline bool operator!=(const stacktrace& lhs, const stacktrace& rhs) BOOST_NOEXCEPT { return !(lhs == rhs); }
|
||||
|
||||
/// Hashing support
|
||||
inline std::size_t hash_value(const stacktrace& st) BOOST_NOEXCEPT {
|
||||
return st.hash_code();
|
||||
}
|
||||
|
||||
/// Outputs stacktrace in a human readable format to output stream.
|
||||
template <class CharT, class TraitsT>
|
||||
std::basic_ostream<CharT, TraitsT>& operator<<(std::basic_ostream<CharT, TraitsT>& os, const stacktrace& bt) {
|
||||
|
||||
@@ -28,10 +28,6 @@ struct backtrace_holder {
|
||||
std::size_t frames_count;
|
||||
boost::shared_ptr<std::string[]> frames;
|
||||
|
||||
BOOST_FORCEINLINE backtrace_holder() BOOST_NOEXCEPT
|
||||
: frames_count(0)
|
||||
{}
|
||||
|
||||
inline std::size_t size() const BOOST_NOEXCEPT {
|
||||
return frames_count;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ struct backtrace_holder {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Dl_info dli;
|
||||
if (!!dladdr(buffer[frame], &dli) && dli.dli_sname) {
|
||||
boost::core::scoped_demangled_name demangled(dli.dli_sname);
|
||||
|
||||
@@ -23,7 +23,7 @@ struct backtrace_holder {
|
||||
inline std::string get_frame(std::size_t /*frame*/) const {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
inline bool operator< (const backtrace_holder& rhs) const BOOST_NOEXCEPT {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -36,10 +36,12 @@ namespace boost { namespace stacktrace {
|
||||
|
||||
stacktrace::stacktrace(const stacktrace& bt) BOOST_NOEXCEPT
|
||||
: impl_(bt.impl_)
|
||||
, hash_code_(bt.hash_code_)
|
||||
{}
|
||||
|
||||
stacktrace& stacktrace::operator=(const stacktrace& bt) BOOST_NOEXCEPT {
|
||||
impl_ = bt.impl_;
|
||||
hash_code_ = bt.hash_code_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -54,11 +56,11 @@ std::string stacktrace::operator[](std::size_t frame) const {
|
||||
}
|
||||
|
||||
bool stacktrace::operator< (const stacktrace& rhs) const BOOST_NOEXCEPT {
|
||||
return impl_ < rhs.impl_;
|
||||
return hash_code_ < rhs.hash_code_ || (hash_code_ == rhs.hash_code_ && impl_ < rhs.impl_);
|
||||
}
|
||||
|
||||
bool stacktrace::operator==(const stacktrace& rhs) const BOOST_NOEXCEPT {
|
||||
return impl_ == rhs.impl_;
|
||||
return hash_code_ == rhs.hash_code_ && impl_ == rhs.impl_;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
#include <boost/stacktrace/detail/backtrace_holder_libunwind.hpp>
|
||||
#include <boost/stacktrace/detail/helpers.hpp>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
namespace boost { namespace stacktrace {
|
||||
|
||||
stacktrace::stacktrace() BOOST_NOEXCEPT {
|
||||
stacktrace::stacktrace() BOOST_NOEXCEPT
|
||||
: hash_code_(0)
|
||||
{
|
||||
boost::stacktrace::detail::backtrace_holder& bt = boost::stacktrace::detail::construct_bt_and_return(impl_);
|
||||
bt.frames_count = 0;
|
||||
|
||||
unw_context_t uc;
|
||||
if (unw_getcontext(&uc) != 0) {
|
||||
@@ -47,6 +52,7 @@ stacktrace::stacktrace() BOOST_NOEXCEPT {
|
||||
std::size_t i = 0;
|
||||
while (unw_step(&cursor) > 0){
|
||||
bt.frames[i] = boost::stacktrace::detail::backtrace_holder::get_frame_impl(cursor);
|
||||
boost::hash_combine(hash_code_, bt.frames[i]);
|
||||
++ i;
|
||||
}
|
||||
} BOOST_CATCH(...) {}
|
||||
|
||||
@@ -16,14 +16,20 @@
|
||||
#include <boost/stacktrace/detail/backtrace_holder_linux.hpp>
|
||||
#include <boost/stacktrace/detail/helpers.hpp>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
namespace boost { namespace stacktrace {
|
||||
|
||||
stacktrace::stacktrace() BOOST_NOEXCEPT {
|
||||
stacktrace::stacktrace() BOOST_NOEXCEPT
|
||||
: hash_code_(0)
|
||||
{
|
||||
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) {
|
||||
if (bt.buffer[bt.frames_count - 1] == 0) {
|
||||
-- bt.frames_count;
|
||||
}
|
||||
|
||||
hash_code_ = boost::hash_range(bt.buffer, bt.buffer + bt.frames_count);
|
||||
}
|
||||
|
||||
}} // namespace boost::stacktrace
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
|
||||
namespace boost { namespace stacktrace {
|
||||
|
||||
stacktrace::stacktrace() BOOST_NOEXCEPT {
|
||||
stacktrace::stacktrace() BOOST_NOEXCEPT
|
||||
: hash_code_(0)
|
||||
{
|
||||
boost::stacktrace::detail::construct_bt_and_return(impl_);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,13 @@
|
||||
|
||||
namespace boost { namespace stacktrace {
|
||||
|
||||
stacktrace::stacktrace() BOOST_NOEXCEPT {
|
||||
stacktrace::stacktrace() BOOST_NOEXCEPT
|
||||
: hash_code_(0)
|
||||
{
|
||||
boost::stacktrace::detail::backtrace_holder& bt = boost::stacktrace::detail::construct_bt_and_return(impl_);
|
||||
bt.frames_count = CaptureStackBackTrace(0, boost::stacktrace::detail::backtrace_holder::max_size, bt.buffer, 0);
|
||||
boost::detail::winapi::ULONG_ hc = 0;
|
||||
bt.frames_count = CaptureStackBackTrace(0, boost::stacktrace::detail::backtrace_holder::max_size, bt.buffer, &hc);
|
||||
boost::hash_combine(hash_code_, hc);
|
||||
}
|
||||
|
||||
}} // namespace boost::stacktrace
|
||||
|
||||
Reference in New Issue
Block a user