]>
Commit | Line | Data |
---|---|---|
92f5a8d4 | 1 | // Copyright Antony Polukhin, 2016-2019. |
b32b8144 FG |
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> | |
92f5a8d4 | 19 | #include <boost/stacktrace/detail/to_dec_array.hpp> |
b32b8144 | 20 | #include <boost/core/demangle.hpp> |
b32b8144 FG |
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; | |
92f5a8d4 TL |
62 | if (size == 0) { |
63 | return res; | |
64 | } | |
b32b8144 FG |
65 | res.reserve(64 * size); |
66 | ||
67 | to_string_impl impl; | |
68 | ||
69 | for (std::size_t i = 0; i < size; ++i) { | |
70 | if (i < 10) { | |
71 | res += ' '; | |
72 | } | |
92f5a8d4 | 73 | res += boost::stacktrace::detail::to_dec_array(i).data(); |
b32b8144 FG |
74 | res += '#'; |
75 | res += ' '; | |
76 | res += impl(frames[i].address()); | |
77 | res += '\n'; | |
78 | } | |
79 | ||
80 | return res; | |
81 | } | |
82 | ||
83 | ||
84 | } // namespace detail | |
85 | ||
86 | ||
87 | std::string frame::name() const { | |
92f5a8d4 TL |
88 | if (!addr_) { |
89 | return std::string(); | |
90 | } | |
91 | ||
b32b8144 FG |
92 | #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) |
93 | ::Dl_info dli; | |
92f5a8d4 | 94 | const bool dl_ok = !!::dladdr(const_cast<void*>(addr_), &dli); // `dladdr` on Solaris accepts nonconst addresses |
b32b8144 FG |
95 | if (dl_ok && dli.dli_sname) { |
96 | return boost::core::demangle(dli.dli_sname); | |
97 | } | |
98 | #endif | |
99 | return boost::stacktrace::detail::name_impl(addr_); | |
100 | } | |
101 | ||
102 | std::string to_string(const frame& f) { | |
92f5a8d4 TL |
103 | if (!f) { |
104 | return std::string(); | |
105 | } | |
106 | ||
b32b8144 FG |
107 | boost::stacktrace::detail::to_string_impl impl; |
108 | return impl(f.address()); | |
109 | } | |
110 | ||
111 | ||
112 | }} // namespace boost::stacktrace | |
113 | ||
114 | #endif // BOOST_STACKTRACE_DETAIL_FRAME_UNWIND_IPP |