summaryrefslogtreecommitdiff
path: root/boost/stacktrace/detail/frame_unwind.ipp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/stacktrace/detail/frame_unwind.ipp')
-rw-r--r--boost/stacktrace/detail/frame_unwind.ipp103
1 files changed, 103 insertions, 0 deletions
diff --git a/boost/stacktrace/detail/frame_unwind.ipp b/boost/stacktrace/detail/frame_unwind.ipp
new file mode 100644
index 0000000000..d4e7973968
--- /dev/null
+++ b/boost/stacktrace/detail/frame_unwind.ipp
@@ -0,0 +1,103 @@
+// Copyright Antony Polukhin, 2016-2017.
+//
+// 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_FRAME_UNWIND_IPP
+#define BOOST_STACKTRACE_DETAIL_FRAME_UNWIND_IPP
+
+#include <boost/config.hpp>
+#ifdef BOOST_HAS_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <boost/stacktrace/frame.hpp>
+
+#include <boost/stacktrace/detail/to_hex_array.hpp>
+#include <boost/stacktrace/detail/location_from_symbol.hpp>
+#include <boost/core/demangle.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <cstdio>
+
+#ifdef BOOST_STACKTRACE_USE_BACKTRACE
+# include <boost/stacktrace/detail/libbacktrace_impls.hpp>
+#elif defined(BOOST_STACKTRACE_USE_ADDR2LINE)
+# include <boost/stacktrace/detail/addr2line_impls.hpp>
+#else
+# include <boost/stacktrace/detail/unwind_base_impls.hpp>
+#endif
+
+namespace boost { namespace stacktrace { namespace detail {
+
+template <class Base>
+class to_string_impl_base: private Base {
+public:
+ std::string operator()(boost::stacktrace::detail::native_frame_ptr_t addr) {
+ Base::res.clear();
+ Base::prepare_function_name(addr);
+ if (!Base::res.empty()) {
+ Base::res = boost::core::demangle(Base::res.c_str());
+ } else {
+ Base::res = to_hex_array(addr).data();
+ }
+
+ if (Base::prepare_source_location(addr)) {
+ return Base::res;
+ }
+
+ boost::stacktrace::detail::location_from_symbol loc(addr);
+ if (!loc.empty()) {
+ Base::res += " in ";
+ Base::res += loc.name();
+ }
+
+ return Base::res;
+ }
+};
+
+std::string to_string(const frame* frames, std::size_t size) {
+ std::string res;
+ res.reserve(64 * size);
+
+ to_string_impl impl;
+
+ for (std::size_t i = 0; i < size; ++i) {
+ if (i < 10) {
+ res += ' ';
+ }
+ res += boost::lexical_cast<boost::array<char, 40> >(i).data();
+ res += '#';
+ res += ' ';
+ res += impl(frames[i].address());
+ res += '\n';
+ }
+
+ return res;
+}
+
+
+} // namespace detail
+
+
+std::string frame::name() const {
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+ ::Dl_info dli;
+ const bool dl_ok = !!::dladdr(addr_, &dli);
+ if (dl_ok && dli.dli_sname) {
+ return boost::core::demangle(dli.dli_sname);
+ }
+#endif
+ return boost::stacktrace::detail::name_impl(addr_);
+}
+
+std::string to_string(const frame& f) {
+ boost::stacktrace::detail::to_string_impl impl;
+ return impl(f.address());
+}
+
+
+}} // namespace boost::stacktrace
+
+#endif // BOOST_STACKTRACE_DETAIL_FRAME_UNWIND_IPP