Skip to content

Commit e617114

Browse files
committed
Add so information to show which dynamic library the function is in.
1 parent f52b0e4 commit e617114

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

itanium/include/fbbe/stacktrace.h

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
// <http://www.gnu.org/licenses/>.
2929

3030
#pragma once
31+
3132
#ifndef _FBBE_GNU_STACKTRACE
3233
#define _FBBE_GNU_STACKTRACE 1
3334

@@ -60,13 +61,26 @@ using stacktrace = std::pmr::stacktrace;
6061

6162
#pragma GCC system_header
6263

64+
#include <charconv>
65+
#include <cstring>
66+
#include <cunistd>
67+
#include <dlfcn.h>
6368
#include <limits>
69+
#include <link.h>
70+
#include <linux/limits.h>
6471
#include <memory>
6572
#include <new>
6673
#include <sstream>
6774
#include <string>
6875
#include <utility>
6976

77+
#if __ELF_NATIVE_CLASS == 32
78+
#define WORD_WIDTH 8
79+
#else
80+
/* We assume 64bits. */
81+
#define WORD_WIDTH 16
82+
#endif
83+
7084
#if __has_include(<compare>)
7185
#include <compare>
7286
#endif
@@ -96,25 +110,24 @@ int backtrace_syminfo(backtrace_state *, __UINTPTR_TYPE__ addr,
96110
#endif
97111

98112
#if defined(_LIBCPP_VERSION) && __has_include(<__assert>)
99-
# include <__assert>
100-
# define _FBBE_ASSERT(pred) _LIBCPP_ASSERT(pred, "")
113+
#include <__assert>
114+
#define _FBBE_ASSERT(pred) _LIBCPP_ASSERT(pred, "")
101115
#elif defined(__GLIBCXX__)
102-
# define _FBBE_ASSERT(pred) __glibcxx_assert(pred)
116+
#define _FBBE_ASSERT(pred) __glibcxx_assert(pred)
103117
#else
104-
# include <cassert>
105-
# define _FBBE_ASSERT(pred) (assert((pred)))
118+
#include <cassert>
119+
#define _FBBE_ASSERT(pred) (assert((pred)))
106120
#endif
107121

108-
#if defined(__GLIBCXX__) || ((defined(__MINGW32__) || defined(__CYGWIN__)) && !defined(__clang__))
109-
#define _FBBE_TRY __try
110-
#define _FBBE_CATCH(x) __catch(x)
122+
#if defined(__GLIBCXX__) || \
123+
((defined(__MINGW32__) || defined(__CYGWIN__)) && !defined(__clang__))
124+
#define _FBBE_TRY __try
125+
#define _FBBE_CATCH(x) __catch(x)
111126
#else
112-
#define _FBBE_TRY try
113-
#define _FBBE_CATCH(x) catch(x)
127+
#define _FBBE_TRY try
128+
#define _FBBE_CATCH(x) catch (x)
114129
#endif
115130

116-
117-
118131
namespace __cxxabiv1 {
119132
extern "C" char *__cxa_demangle(const char *__mangled_name,
120133
char *__output_buffer, size_t *__length,
@@ -224,13 +237,34 @@ class stacktrace_entry {
224237
static void _S_err_handler(void *, const char *, int) {}
225238

226239
static backtrace_state *_S_init() {
227-
static backtrace_state *__state =
228-
backtrace_create_state(nullptr, 1, _S_err_handler, nullptr);
240+
static backtrace_state *__state = []() {
241+
auto getpath = []() -> std::string {
242+
char buf[PATH_MAX + 1];
243+
if (readlink("/proc/self/exe", buf, sizeof(buf) - 1) == -1) {
244+
return "";
245+
}
246+
std::string str(buf);
247+
return str.substr(0, str.rfind('/'));
248+
};
249+
250+
auto exec_filename = getpath();
251+
return backtrace_create_state(exec_filename.c_str(), 1, _S_err_handler,
252+
nullptr);
253+
}();
229254
return __state;
230255
}
231256

232257
friend std::ostream &operator<<(std::ostream &, const stacktrace_entry &);
233258

259+
std::string _symbol(uintptr_t const pc) const {
260+
Dl_info info;
261+
int status;
262+
link_map *map;
263+
status = dladdr1((void const *)(pc), &info, reinterpret_cast<void **>(&map),
264+
RTLD_DL_LINKMAP);
265+
return std::string(info.dli_fname ?: "");
266+
}
267+
234268
bool _M_get_info(std::string *__desc, std::string *__file,
235269
int *__line) const {
236270
if (!*this)
@@ -687,9 +721,7 @@ template <typename _Allocator> class basic_stacktrace {
687721
return nullptr;
688722
_M_frames = static_cast<pointer>(__p);
689723
} else {
690-
_FBBE_TRY {
691-
_M_frames = __alloc.allocate(__n);
692-
}
724+
_FBBE_TRY { _M_frames = __alloc.allocate(__n); }
693725
_FBBE_CATCH(const std::bad_alloc &) { return nullptr; }
694726
}
695727
_M_capacity = __n;
@@ -706,7 +738,7 @@ template <typename _Allocator> class basic_stacktrace {
706738
_FBBE_GNU_OPERATOR_DELETE(static_cast<void *>(_M_frames),
707739
_M_capacity * sizeof(value_type));
708740
#else
709-
_FBBE_GNU_OPERATOR_DELETE(static_cast<void *>(_M_frames));
741+
_FBBE_GNU_OPERATOR_DELETE(static_cast<void *>(_M_frames));
710742
#endif
711743
else
712744
__alloc.deallocate(_M_frames, _M_capacity);
@@ -803,7 +835,8 @@ inline std::ostream &operator<<(std::ostream &__os,
803835
int __line;
804836
if (__f._M_get_info(&__desc, &__file, &__line)) {
805837
__os.width(4);
806-
__os << __desc << " at " << __file << ':' << __line;
838+
__os << __f._symbol(__f._M_pc) << "(" << __desc << ") at " << __file << ':'
839+
<< __line;
807840
}
808841
return __os;
809842
}

0 commit comments

Comments
 (0)