diff --git a/itanium/include/fbbe/stacktrace.h b/itanium/include/fbbe/stacktrace.h
index b3290b1..096c53b 100644
--- a/itanium/include/fbbe/stacktrace.h
+++ b/itanium/include/fbbe/stacktrace.h
@@ -28,6 +28,7 @@
// .
#pragma once
+
#ifndef _FBBE_GNU_STACKTRACE
#define _FBBE_GNU_STACKTRACE 1
@@ -60,13 +61,26 @@ using stacktrace = std::pmr::stacktrace;
#pragma GCC system_header
+#include
+#include
+#include
+#include
#include
+#include
+#include
#include
#include
#include
#include
#include
+#if __ELF_NATIVE_CLASS == 32
+#define WORD_WIDTH 8
+#else
+/* We assume 64bits. */
+#define WORD_WIDTH 16
+#endif
+
#if __has_include()
#include
#endif
@@ -96,25 +110,24 @@ int backtrace_syminfo(backtrace_state *, __UINTPTR_TYPE__ addr,
#endif
#if defined(_LIBCPP_VERSION) && __has_include(<__assert>)
-# include <__assert>
-# define _FBBE_ASSERT(pred) _LIBCPP_ASSERT(pred, "")
+#include <__assert>
+#define _FBBE_ASSERT(pred) _LIBCPP_ASSERT(pred, "")
#elif defined(__GLIBCXX__)
-# define _FBBE_ASSERT(pred) __glibcxx_assert(pred)
+#define _FBBE_ASSERT(pred) __glibcxx_assert(pred)
#else
-# include
-# define _FBBE_ASSERT(pred) (assert((pred)))
+#include
+#define _FBBE_ASSERT(pred) (assert((pred)))
#endif
-#if defined(__GLIBCXX__) || ((defined(__MINGW32__) || defined(__CYGWIN__)) && !defined(__clang__))
- #define _FBBE_TRY __try
- #define _FBBE_CATCH(x) __catch(x)
+#if defined(__GLIBCXX__) || \
+ ((defined(__MINGW32__) || defined(__CYGWIN__)) && !defined(__clang__))
+#define _FBBE_TRY __try
+#define _FBBE_CATCH(x) __catch(x)
#else
- #define _FBBE_TRY try
- #define _FBBE_CATCH(x) catch(x)
+#define _FBBE_TRY try
+#define _FBBE_CATCH(x) catch (x)
#endif
-
-
namespace __cxxabiv1 {
extern "C" char *__cxa_demangle(const char *__mangled_name,
char *__output_buffer, size_t *__length,
@@ -224,13 +237,34 @@ class stacktrace_entry {
static void _S_err_handler(void *, const char *, int) {}
static backtrace_state *_S_init() {
- static backtrace_state *__state =
- backtrace_create_state(nullptr, 1, _S_err_handler, nullptr);
+ static backtrace_state *__state = []() {
+ auto getpath = []() -> std::string {
+ char buf[PATH_MAX + 1];
+ if (readlink("/proc/self/exe", buf, sizeof(buf) - 1) == -1) {
+ return "";
+ }
+ std::string str(buf);
+ return str.substr(0, str.rfind('/'));
+ };
+
+ auto exec_filename = getpath();
+ return backtrace_create_state(exec_filename.c_str(), 1, _S_err_handler,
+ nullptr);
+ }();
return __state;
}
friend std::ostream &operator<<(std::ostream &, const stacktrace_entry &);
+ std::string _symbol(uintptr_t const pc) const {
+ Dl_info info;
+ int status;
+ link_map *map;
+ status = dladdr1((void const *)(pc), &info, reinterpret_cast(&map),
+ RTLD_DL_LINKMAP);
+ return std::string(info.dli_fname ?: "");
+ }
+
bool _M_get_info(std::string *__desc, std::string *__file,
int *__line) const {
if (!*this)
@@ -687,9 +721,7 @@ template class basic_stacktrace {
return nullptr;
_M_frames = static_cast(__p);
} else {
- _FBBE_TRY {
- _M_frames = __alloc.allocate(__n);
- }
+ _FBBE_TRY { _M_frames = __alloc.allocate(__n); }
_FBBE_CATCH(const std::bad_alloc &) { return nullptr; }
}
_M_capacity = __n;
@@ -706,7 +738,7 @@ template class basic_stacktrace {
_FBBE_GNU_OPERATOR_DELETE(static_cast(_M_frames),
_M_capacity * sizeof(value_type));
#else
- _FBBE_GNU_OPERATOR_DELETE(static_cast(_M_frames));
+ _FBBE_GNU_OPERATOR_DELETE(static_cast(_M_frames));
#endif
else
__alloc.deallocate(_M_frames, _M_capacity);
@@ -803,7 +835,8 @@ inline std::ostream &operator<<(std::ostream &__os,
int __line;
if (__f._M_get_info(&__desc, &__file, &__line)) {
__os.width(4);
- __os << __desc << " at " << __file << ':' << __line;
+ __os << __f._symbol(__f._M_pc) << "(" << __desc << ") at " << __file << ':'
+ << __line;
}
return __os;
}