diff --git a/include/cpptrace/cpptrace.hpp b/include/cpptrace/cpptrace.hpp index 681d105..ce35914 100644 --- a/include/cpptrace/cpptrace.hpp +++ b/include/cpptrace/cpptrace.hpp @@ -22,8 +22,10 @@ namespace cpptrace { struct object_trace; struct stacktrace; + using frame_ptr = std::uintptr_t; + struct CPPTRACE_EXPORT raw_trace { - std::vector frames; + std::vector frames; static raw_trace current(std::uint_least32_t skip = 0); static raw_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth); object_trace resolve_object_trace() const; @@ -31,8 +33,8 @@ namespace cpptrace { void clear(); bool empty() const noexcept; - using iterator = std::vector::iterator; - using const_iterator = std::vector::const_iterator; + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; inline iterator begin() noexcept { return frames.begin(); } inline iterator end() noexcept { return frames.end(); } inline const_iterator begin() const noexcept { return frames.begin(); } @@ -44,8 +46,8 @@ namespace cpptrace { struct CPPTRACE_EXPORT object_frame { std::string obj_path; std::string symbol; - std::uintptr_t raw_address = 0; - std::uintptr_t obj_address = 0; + frame_ptr raw_address = 0; + frame_ptr obj_address = 0; }; struct CPPTRACE_EXPORT object_trace { @@ -67,7 +69,7 @@ namespace cpptrace { }; struct CPPTRACE_EXPORT stacktrace_frame { - std::uintptr_t address; + frame_ptr address; std::uint_least32_t line; // TODO: This should use UINT_LEAST32_MAX as a sentinel std::uint_least32_t column; // UINT_LEAST32_MAX if not present std::string filename; diff --git a/src/cpptrace.cpp b/src/cpptrace.cpp index bdf113e..c0634c6 100644 --- a/src/cpptrace.cpp +++ b/src/cpptrace.cpp @@ -111,7 +111,7 @@ namespace cpptrace { stream << std::hex << "0x" - << std::setw(2 * sizeof(std::uintptr_t)) + << std::setw(2 * sizeof(frame_ptr)) << std::setfill('0') << frame.address << std::dec @@ -178,14 +178,14 @@ namespace cpptrace { << " "; if(frame.is_inline) { stream - << std::setw(2 * sizeof(std::uintptr_t) + 2) + << std::setw(2 * sizeof(frame_ptr) + 2) << "(inlined)"; } else { stream << std::hex << blue << "0x" - << std::setw(2 * sizeof(std::uintptr_t)) + << std::setw(2 * sizeof(frame_ptr)) << std::setfill('0') << frame.address << std::dec @@ -295,7 +295,7 @@ namespace cpptrace { CPPTRACE_FORCE_NO_INLINE stacktrace generate_trace(std::uint32_t skip, std::uint_least32_t max_depth) { try { - std::vector frames = detail::capture_frames(skip + 1, max_depth); + std::vector frames = detail::capture_frames(skip + 1, max_depth); std::vector trace = detail::resolve_frames(frames); for(auto& frame : trace) { frame.symbol = detail::demangle(frame.symbol); diff --git a/src/platform/object.hpp b/src/platform/object.hpp index 97d1a55..aaec42d 100644 --- a/src/platform/object.hpp +++ b/src/platform/object.hpp @@ -62,11 +62,11 @@ namespace detail { } #endif // aladdr queries are needed to get pre-ASLR addresses and targets to run addr2line on - inline std::vector get_frames_object_info(const std::vector& addrs) { + inline std::vector get_frames_object_info(const std::vector& addrs) { // reference: https://github.com/bminor/glibc/blob/master/debug/backtracesyms.c std::vector frames; frames.reserve(addrs.size()); - for(const std::uintptr_t addr : addrs) { + for(const frame_ptr addr : addrs) { Dl_info info; object_frame frame; frame.raw_address = addr; @@ -122,11 +122,11 @@ namespace detail { } // aladdr queries are needed to get pre-ASLR addresses and targets to run addr2line on - inline std::vector get_frames_object_info(const std::vector& addrs) { + inline std::vector get_frames_object_info(const std::vector& addrs) { // reference: https://github.com/bminor/glibc/blob/master/debug/backtracesyms.c std::vector frames; frames.reserve(addrs.size()); - for(const std::uintptr_t addr : addrs) { + for(const frame_ptr addr : addrs) { object_frame frame; frame.raw_address = addr; HMODULE handle; diff --git a/src/platform/utils.hpp b/src/platform/utils.hpp index 1760ac8..5097d8f 100644 --- a/src/platform/utils.hpp +++ b/src/platform/utils.hpp @@ -352,8 +352,8 @@ namespace detail { return static_cast(t); } template - std::uintptr_t to_uintptr(T t) { - return static_cast(t); + frame_ptr to_frame_ptr(T t) { + return static_cast(t); } // A way to cast to U without "warning: useless cast to type" diff --git a/src/symbols/symbols.hpp b/src/symbols/symbols.hpp index 3a4060d..a8f69e6 100644 --- a/src/symbols/symbols.hpp +++ b/src/symbols/symbols.hpp @@ -32,7 +32,7 @@ namespace detail { #ifdef CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE namespace libbacktrace { - std::vector resolve_frames(const std::vector& frames); + std::vector resolve_frames(const std::vector& frames); } #endif #ifdef CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF @@ -42,7 +42,7 @@ namespace detail { #endif #ifdef CPPTRACE_GET_SYMBOLS_WITH_LIBDL namespace libdl { - std::vector resolve_frames(const std::vector& frames); + std::vector resolve_frames(const std::vector& frames); } #endif #ifdef CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE @@ -52,18 +52,18 @@ namespace detail { #endif #ifdef CPPTRACE_GET_SYMBOLS_WITH_DBGHELP namespace dbghelp { - std::vector resolve_frames(const std::vector& frames); + std::vector resolve_frames(const std::vector& frames); } #endif #ifdef CPPTRACE_GET_SYMBOLS_WITH_NOTHING namespace nothing { std::vector resolve_frames(const std::vector& frames); - std::vector resolve_frames(const std::vector& frames); + std::vector resolve_frames(const std::vector& frames); } #endif std::vector resolve_frames(const std::vector& frames); - std::vector resolve_frames(const std::vector& frames); + std::vector resolve_frames(const std::vector& frames); } } diff --git a/src/symbols/symbols_core.cpp b/src/symbols/symbols_core.cpp index 14fd19c..38ba921 100644 --- a/src/symbols/symbols_core.cpp +++ b/src/symbols/symbols_core.cpp @@ -84,7 +84,7 @@ namespace detail { || defined(CPPTRACE_GET_SYMBOLS_WITH_DBGHELP) \ || defined(CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE) // actually need to go backwards to a void* - std::vector raw_frames(frames.size()); + std::vector raw_frames(frames.size()); for(std::size_t i = 0; i < frames.size(); i++) { raw_frames[i] = frames[i].raw_address; } @@ -110,7 +110,7 @@ namespace detail { return trace; } - std::vector resolve_frames(const std::vector& frames) { + std::vector resolve_frames(const std::vector& frames) { #if defined(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF) \ || defined(CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE) auto dlframes = get_frames_object_info(frames); diff --git a/src/symbols/symbols_with_dbghelp.cpp b/src/symbols/symbols_with_dbghelp.cpp index e5f93b0..c4b26a0 100644 --- a/src/symbols/symbols_with_dbghelp.cpp +++ b/src/symbols/symbols_with_dbghelp.cpp @@ -325,7 +325,7 @@ namespace dbghelp { std::recursive_mutex dbghelp_lock; // TODO: Handle backtrace_pcinfo calling the callback multiple times on inlined functions - stacktrace_frame resolve_frame(HANDLE proc, std::uintptr_t addr) { + stacktrace_frame resolve_frame(HANDLE proc, frame_ptr addr) { const std::lock_guard lock(dbghelp_lock); // all dbghelp functions are not thread safe alignas(SYMBOL_INFO) char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; SYMBOL_INFO* symbol = (SYMBOL_INFO*)buffer; @@ -390,7 +390,7 @@ namespace dbghelp { } } - std::vector resolve_frames(const std::vector& frames) { + std::vector resolve_frames(const std::vector& frames) { const std::lock_guard lock(dbghelp_lock); // all dbghelp functions are not thread safe std::vector trace; trace.reserve(frames.size()); diff --git a/src/symbols/symbols_with_dl.cpp b/src/symbols/symbols_with_dl.cpp index 3de3a2c..11578c1 100644 --- a/src/symbols/symbols_with_dl.cpp +++ b/src/symbols/symbols_with_dl.cpp @@ -12,7 +12,7 @@ namespace cpptrace { namespace detail { namespace libdl { - stacktrace_frame resolve_frame(const std::uintptr_t addr) { + stacktrace_frame resolve_frame(const frame_ptr addr) { Dl_info info; if(dladdr(reinterpret_cast(addr), &info)) { // thread-safe return { @@ -33,7 +33,7 @@ namespace libdl { } } - std::vector resolve_frames(const std::vector& frames) { + std::vector resolve_frames(const std::vector& frames) { std::vector trace; trace.reserve(frames.size()); for(const auto frame : frames) { diff --git a/src/symbols/symbols_with_libbacktrace.cpp b/src/symbols/symbols_with_libbacktrace.cpp index cc9c8af..6732ec1 100644 --- a/src/symbols/symbols_with_libbacktrace.cpp +++ b/src/symbols/symbols_with_libbacktrace.cpp @@ -55,7 +55,7 @@ namespace libbacktrace { } // TODO: Handle backtrace_pcinfo calling the callback multiple times on inlined functions - stacktrace_frame resolve_frame(const std::uintptr_t addr) { + stacktrace_frame resolve_frame(const frame_ptr addr) { try { stacktrace_frame frame; frame.column = UINT_LEAST32_MAX; @@ -85,7 +85,7 @@ namespace libbacktrace { } } - std::vector resolve_frames(const std::vector& frames) { + std::vector resolve_frames(const std::vector& frames) { std::vector trace; trace.reserve(frames.size()); for(const auto frame : frames) { diff --git a/src/symbols/symbols_with_nothing.cpp b/src/symbols/symbols_with_nothing.cpp index 9d85085..f2d7741 100644 --- a/src/symbols/symbols_with_nothing.cpp +++ b/src/symbols/symbols_with_nothing.cpp @@ -8,7 +8,7 @@ namespace cpptrace { namespace detail { namespace nothing { - std::vector resolve_frames(const std::vector& frames) { + std::vector resolve_frames(const std::vector& frames) { return std::vector(frames.size(), null_frame); } diff --git a/src/unwind/unwind.hpp b/src/unwind/unwind.hpp index 404901c..f42588c 100644 --- a/src/unwind/unwind.hpp +++ b/src/unwind/unwind.hpp @@ -15,7 +15,7 @@ namespace detail { constexpr std::size_t hard_max_frames = 100; #endif CPPTRACE_FORCE_NO_INLINE - std::vector capture_frames(std::size_t skip, std::size_t max_depth); + std::vector capture_frames(std::size_t skip, std::size_t max_depth); } } diff --git a/src/unwind/unwind_with_dbghelp.cpp b/src/unwind/unwind_with_dbghelp.cpp index 9aa9388..4e912c9 100644 --- a/src/unwind/unwind_with_dbghelp.cpp +++ b/src/unwind/unwind_with_dbghelp.cpp @@ -26,7 +26,7 @@ namespace detail { #pragma warning(disable: 4740) // warning C4740: flow in or out of inline asm code suppresses global optimization #endif CPPTRACE_FORCE_NO_INLINE - std::vector capture_frames(std::size_t skip, std::size_t max_depth) { + std::vector capture_frames(std::size_t skip, std::size_t max_depth) { skip++; // https://jpassing.com/2008/03/12/walking-the-stack-of-the-current-thread/ @@ -94,7 +94,7 @@ namespace detail { #error "Cpptrace: StackWalk64 not supported for this platform yet" #endif - std::vector trace; + std::vector trace; // Dbghelp is is single-threaded, so acquire a lock. static std::mutex mutex; @@ -138,7 +138,7 @@ namespace detail { // On x86/x64/arm, as far as I can tell, the frame return address is always one after the call // So we just decrement to get the pc back inside the `call` / `bl` // This is done with _Unwind too but conditionally based on info from _Unwind_GetIPInfo. - trace.push_back(to_uintptr(frame.AddrPC.Offset) - 1); + trace.push_back(to_frame_ptr(frame.AddrPC.Offset) - 1); } } else { // base diff --git a/src/unwind/unwind_with_execinfo.cpp b/src/unwind/unwind_with_execinfo.cpp index db3b774..3f4c2fa 100644 --- a/src/unwind/unwind_with_execinfo.cpp +++ b/src/unwind/unwind_with_execinfo.cpp @@ -13,17 +13,17 @@ namespace cpptrace { namespace detail { CPPTRACE_FORCE_NO_INLINE - std::vector capture_frames(std::size_t skip, std::size_t max_depth) { + std::vector capture_frames(std::size_t skip, std::size_t max_depth) { skip++; std::vector addrs(std::min(hard_max_frames, skip + max_depth), nullptr); const int n_frames = backtrace(addrs.data(), static_cast(addrs.size())); // thread safe // I hate the copy here but it's the only way that isn't UB - std::vector frames(n_frames - skip, 0); + std::vector frames(n_frames - skip, 0); for(int i = skip; i < n_frames; i++) { // On x86/x64/arm, as far as I can tell, the frame return address is always one after the call // So we just decrement to get the pc back inside the `call` / `bl` // This is done with _Unwind too but conditionally based on info from _Unwind_GetIPInfo. - frames[i - skip] = reinterpret_cast(addrs[i]) - 1; + frames[i - skip] = reinterpret_cast(addrs[i]) - 1; } return frames; } diff --git a/src/unwind/unwind_with_nothing.cpp b/src/unwind/unwind_with_nothing.cpp index 0768763..55ebf27 100644 --- a/src/unwind/unwind_with_nothing.cpp +++ b/src/unwind/unwind_with_nothing.cpp @@ -7,7 +7,7 @@ namespace cpptrace { namespace detail { - std::vector capture_frames(std::size_t, std::size_t) { + std::vector capture_frames(std::size_t, std::size_t) { return {}; } } diff --git a/src/unwind/unwind_with_unwind.cpp b/src/unwind/unwind_with_unwind.cpp index 3d308ca..a38a342 100644 --- a/src/unwind/unwind_with_unwind.cpp +++ b/src/unwind/unwind_with_unwind.cpp @@ -17,14 +17,14 @@ namespace detail { struct unwind_state { std::size_t skip; std::size_t count; - std::vector& vec; + std::vector& vec; }; _Unwind_Reason_Code unwind_callback(_Unwind_Context* context, void* arg) { unwind_state& state = *static_cast(arg); if(state.skip) { state.skip--; - if(_Unwind_GetIP(context) == std::uintptr_t(0)) { + if(_Unwind_GetIP(context) == frame_ptr(0)) { return _URC_END_OF_STACK; } else { return _URC_NO_REASON; @@ -36,11 +36,11 @@ namespace detail { "Somehow cpptrace::detail::unwind_callback is overflowing a vector" ); int is_before_instruction = 0; - std::uintptr_t ip = _Unwind_GetIPInfo(context, &is_before_instruction); - if(!is_before_instruction && ip != std::uintptr_t(0)) { + frame_ptr ip = _Unwind_GetIPInfo(context, &is_before_instruction); + if(!is_before_instruction && ip != frame_ptr(0)) { ip--; } - if (ip == std::uintptr_t(0)) { + if (ip == frame_ptr(0)) { return _URC_END_OF_STACK; } else { // TODO: push_back?... @@ -54,8 +54,8 @@ namespace detail { } CPPTRACE_FORCE_NO_INLINE - std::vector capture_frames(std::size_t skip, std::size_t max_depth) { - std::vector frames(std::min(hard_max_frames, max_depth), 0); + std::vector capture_frames(std::size_t skip, std::size_t max_depth) { + std::vector frames(std::min(hard_max_frames, max_depth), 0); unwind_state state{skip + 1, 0, frames}; _Unwind_Backtrace(unwind_callback, &state); // presumably thread-safe frames.resize(state.count); diff --git a/src/unwind/unwind_with_winapi.cpp b/src/unwind/unwind_with_winapi.cpp index 9de15f0..42e3a3e 100644 --- a/src/unwind/unwind_with_winapi.cpp +++ b/src/unwind/unwind_with_winapi.cpp @@ -19,7 +19,7 @@ namespace cpptrace { namespace detail { CPPTRACE_FORCE_NO_INLINE - std::vector capture_frames(std::size_t skip, std::size_t max_depth) { + std::vector capture_frames(std::size_t skip, std::size_t max_depth) { std::vector addrs(std::min(hard_max_frames, max_depth), nullptr); int n_frames = CaptureStackBackTrace( static_cast(skip + 1), @@ -28,12 +28,12 @@ namespace detail { NULL ); // I hate the copy here but it's the only way that isn't UB - std::vector frames(n_frames, 0); + std::vector frames(n_frames, 0); for(std::size_t i = 0; i < n_frames; i++) { // On x86/x64/arm, as far as I can tell, the frame return address is always one after the call // So we just decrement to get the pc back inside the `call` / `bl` // This is done with _Unwind too but conditionally based on info from _Unwind_GetIPInfo. - frames[i] = reinterpret_cast(addrs[i]) - 1; + frames[i] = reinterpret_cast(addrs[i]) - 1; } return frames; }