]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/stacktrace/detail/frame_unwind.ipp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / stacktrace / detail / frame_unwind.ipp
1 // Copyright Antony Polukhin, 2016-2017.
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6
7 #ifndef BOOST_STACKTRACE_DETAIL_FRAME_UNWIND_IPP
8 #define BOOST_STACKTRACE_DETAIL_FRAME_UNWIND_IPP
9
10 #include <boost/config.hpp>
11 #ifdef BOOST_HAS_PRAGMA_ONCE
12 # pragma once
13 #endif
14
15 #include <boost/stacktrace/frame.hpp>
16
17 #include <boost/stacktrace/detail/to_hex_array.hpp>
18 #include <boost/stacktrace/detail/location_from_symbol.hpp>
19 #include <boost/core/demangle.hpp>
20 #include <boost/lexical_cast.hpp>
21
22 #include <cstdio>
23
24 #ifdef BOOST_STACKTRACE_USE_BACKTRACE
25 # include <boost/stacktrace/detail/libbacktrace_impls.hpp>
26 #elif defined(BOOST_STACKTRACE_USE_ADDR2LINE)
27 # include <boost/stacktrace/detail/addr2line_impls.hpp>
28 #else
29 # include <boost/stacktrace/detail/unwind_base_impls.hpp>
30 #endif
31
32 namespace boost { namespace stacktrace { namespace detail {
33
34 template <class Base>
35 class to_string_impl_base: private Base {
36 public:
37 std::string operator()(boost::stacktrace::detail::native_frame_ptr_t addr) {
38 Base::res.clear();
39 Base::prepare_function_name(addr);
40 if (!Base::res.empty()) {
41 Base::res = boost::core::demangle(Base::res.c_str());
42 } else {
43 Base::res = to_hex_array(addr).data();
44 }
45
46 if (Base::prepare_source_location(addr)) {
47 return Base::res;
48 }
49
50 boost::stacktrace::detail::location_from_symbol loc(addr);
51 if (!loc.empty()) {
52 Base::res += " in ";
53 Base::res += loc.name();
54 }
55
56 return Base::res;
57 }
58 };
59
60 std::string to_string(const frame* frames, std::size_t size) {
61 std::string res;
62 res.reserve(64 * size);
63
64 to_string_impl impl;
65
66 for (std::size_t i = 0; i < size; ++i) {
67 if (i < 10) {
68 res += ' ';
69 }
70 res += boost::lexical_cast<boost::array<char, 40> >(i).data();
71 res += '#';
72 res += ' ';
73 res += impl(frames[i].address());
74 res += '\n';
75 }
76
77 return res;
78 }
79
80
81 } // namespace detail
82
83
84 std::string frame::name() const {
85 #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
86 ::Dl_info dli;
87 const bool dl_ok = !!::dladdr(addr_, &dli);
88 if (dl_ok && dli.dli_sname) {
89 return boost::core::demangle(dli.dli_sname);
90 }
91 #endif
92 return boost::stacktrace::detail::name_impl(addr_);
93 }
94
95 std::string to_string(const frame& f) {
96 boost::stacktrace::detail::to_string_impl impl;
97 return impl(f.address());
98 }
99
100
101 }} // namespace boost::stacktrace
102
103 #endif // BOOST_STACKTRACE_DETAIL_FRAME_UNWIND_IPP