From 5c3df2571e678a8b2a1440f065abc922121fafba Mon Sep 17 00:00:00 2001 From: Jeremy <51220084+jeremy-rifkin@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:15:33 -0400 Subject: [PATCH] Rename stacktrace_frame.col to column, set a proper sentinel value, and update stacktrace.to_string to not have a tailing newline --- README.md | 2 +- include/cpptrace/cpptrace.hpp | 6 +++-- src/cpptrace.cpp | 32 +++++++++++++++++------ src/symbols/symbols_core.cpp | 4 +-- src/symbols/symbols_with_addr2line.cpp | 2 +- src/symbols/symbols_with_dbghelp.cpp | 8 +++--- src/symbols/symbols_with_dl.cpp | 4 +-- src/symbols/symbols_with_libbacktrace.cpp | 1 - src/symbols/symbols_with_libdwarf.cpp | 2 +- src/symbols/symbols_with_nothing.cpp | 16 ++---------- 10 files changed, 41 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index a34162a..7576b6e 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ namespace cpptrace { struct stacktrace_frame { uintptr_t address; std::uint_least32_t line; - std::uint_least32_t col; + std::uint_least32_t column; // UINT_LEAST32_MAX if not present std::string filename; std::string symbol; bool operator==(const stacktrace_frame& other) const; diff --git a/include/cpptrace/cpptrace.hpp b/include/cpptrace/cpptrace.hpp index d944edd..d858621 100644 --- a/include/cpptrace/cpptrace.hpp +++ b/include/cpptrace/cpptrace.hpp @@ -56,13 +56,13 @@ namespace cpptrace { struct stacktrace_frame { uintptr_t address; std::uint_least32_t line; - std::uint_least32_t col; + std::uint_least32_t column = UINT_LEAST32_MAX; // UINT_LEAST32_MAX if not present std::string filename; std::string symbol; bool operator==(const stacktrace_frame& other) const { return address == other.address && line == other.line - && col == other.col + && column == other.column && filename == other.filename && symbol == other.symbol; } @@ -86,6 +86,8 @@ namespace cpptrace { inline const_iterator cbegin() const noexcept { return frames.cbegin(); } inline iterator end() noexcept { return frames.end(); } inline const_iterator cend() const noexcept { return frames.cend(); } + private: + CPPTRACE_API void print(std::ostream& stream, bool color, bool newline_at_end) const; }; CPPTRACE_API raw_trace generate_raw_trace(std::uint32_t skip = 0); diff --git a/src/cpptrace.cpp b/src/cpptrace.cpp index 269d214..99b2b1f 100644 --- a/src/cpptrace.cpp +++ b/src/cpptrace.cpp @@ -66,6 +66,11 @@ namespace cpptrace { CPPTRACE_API void stacktrace::print(std::ostream& stream, bool color) const { + print(stream, color, true); + } + + CPPTRACE_API + void stacktrace::print(std::ostream& stream, bool color, bool newline_at_end) const { if(color) { detail::enable_virtual_terminal_processing_if_needed(); } @@ -100,20 +105,31 @@ namespace cpptrace { << " at " << (color ? GREEN : "") << frame.filename - << (color ? RESET : "") - << ":" - << (color ? BLUE : "") - << frame.line - << (color ? RESET : "") - << (frame.col > 0 ? (color ? ":" BLUE : ":") + std::to_string(frame.col) + (color ? RESET : "") : "") - << std::endl; + << (color ? RESET : ""); + if(frame.line != 0) { + stream + << ":" + << (color ? BLUE : "") + << frame.line + << (color ? RESET : ""); + if(frame.column != UINT_LEAST32_MAX) { + stream << ( + frame.column > 0 + ? (color ? ":" BLUE : ":") + std::to_string(frame.column) + (color ? RESET : "") + : "" + ); + } + } + if(newline_at_end || &frame != &frames.back()) { + stream << std::endl; + } } } CPPTRACE_API std::string stacktrace::to_string() const { std::ostringstream oss; - print(oss, false); + print(oss, false, false); return std::move(oss).str(); } diff --git a/src/symbols/symbols_core.cpp b/src/symbols/symbols_core.cpp index 10128db..3726758 100644 --- a/src/symbols/symbols_core.cpp +++ b/src/symbols/symbols_core.cpp @@ -38,8 +38,8 @@ namespace detail { if(result[i].line == 0) { result[i].line = trace[i].line; } - if(result[i].col == 0) { - result[i].col = trace[i].col; + if(result[i].column == 0) { + result[i].column = trace[i].column; } if(result[i].filename.empty()) { result[i].filename = std::move(trace[i].filename); diff --git a/src/symbols/symbols_with_addr2line.cpp b/src/symbols/symbols_with_addr2line.cpp index 8af13b8..0a739fe 100644 --- a/src/symbols/symbols_with_addr2line.cpp +++ b/src/symbols/symbols_with_addr2line.cpp @@ -273,7 +273,7 @@ namespace addr2line { // NOLINTNEXTLINE(readability-convert-member-functions-to-static) std::vector resolve_frames(const std::vector& frames) { // TODO: Refactor better - std::vector trace(frames.size(), stacktrace_frame { 0, 0, 0, "", "" }); + std::vector trace(frames.size()); for(size_t i = 0; i < frames.size(); i++) { trace[i].address = frames[i].raw_address; // Set what is known for now, and resolutions from addr2line should overwrite diff --git a/src/symbols/symbols_with_dbghelp.cpp b/src/symbols/symbols_with_dbghelp.cpp index d98fb37..3041e48 100644 --- a/src/symbols/symbols_with_dbghelp.cpp +++ b/src/symbols/symbols_with_dbghelp.cpp @@ -346,7 +346,7 @@ namespace dbghelp { return { addr, static_cast(line.LineNumber), - 0, + UINT_LEAST32_MAX, line.FileName, symbol->Name }; @@ -377,7 +377,7 @@ namespace dbghelp { return { addr, static_cast(line.LineNumber), - 0, + UINT_LEAST32_MAX, line.FileName, signature }; @@ -385,7 +385,7 @@ namespace dbghelp { return { addr, 0, - 0, + UINT_LEAST32_MAX, "", symbol->Name }; @@ -394,7 +394,7 @@ namespace dbghelp { return { addr, 0, - 0, + UINT_LEAST32_MAX, "", "" }; diff --git a/src/symbols/symbols_with_dl.cpp b/src/symbols/symbols_with_dl.cpp index 8c4ac92..bc0771e 100644 --- a/src/symbols/symbols_with_dl.cpp +++ b/src/symbols/symbols_with_dl.cpp @@ -18,7 +18,7 @@ namespace libdl { return { addr, 0, - 0, + UINT_LEAST32_MAX, info.dli_fname ? info.dli_fname : "", info.dli_sname ? info.dli_sname : "" }; @@ -26,7 +26,7 @@ namespace libdl { return { addr, 0, - 0, + UINT_LEAST32_MAX, "", "" }; diff --git a/src/symbols/symbols_with_libbacktrace.cpp b/src/symbols/symbols_with_libbacktrace.cpp index 78a307d..40d6593 100644 --- a/src/symbols/symbols_with_libbacktrace.cpp +++ b/src/symbols/symbols_with_libbacktrace.cpp @@ -60,7 +60,6 @@ namespace libbacktrace { // TODO: Handle backtrace_pcinfo calling the callback multiple times on inlined functions stacktrace_frame resolve_frame(const uintptr_t addr) { stacktrace_frame frame; - frame.col = 0; backtrace_pcinfo( get_backtrace_state(), addr, diff --git a/src/symbols/symbols_with_libdwarf.cpp b/src/symbols/symbols_with_libdwarf.cpp index cd4e278..e537a03 100644 --- a/src/symbols/symbols_with_libdwarf.cpp +++ b/src/symbols/symbols_with_libdwarf.cpp @@ -1037,7 +1037,7 @@ namespace libdwarf { CPPTRACE_FORCE_NO_INLINE_FOR_PROFILING std::vector resolve_frames(const std::vector& frames) { - std::vector trace(frames.size(), stacktrace_frame { 0, 0, 0, "", "" }); + std::vector trace(frames.size()); for(const auto& obj_entry : collate_frames(frames, trace)) { const auto& obj_name = obj_entry.first; dwarf_resolver resolver(obj_name); diff --git a/src/symbols/symbols_with_nothing.cpp b/src/symbols/symbols_with_nothing.cpp index 46a3762..35f802f 100644 --- a/src/symbols/symbols_with_nothing.cpp +++ b/src/symbols/symbols_with_nothing.cpp @@ -9,23 +9,11 @@ namespace cpptrace { namespace detail { namespace nothing { std::vector resolve_frames(const std::vector& frames) { - return std::vector(frames.size(), { - 0, - 0, - 0, - "", - "" - }); + return std::vector(frames.size()); } std::vector resolve_frames(const std::vector& frames) { - return std::vector(frames.size(), { - 0, - 0, - 0, - "", - "" - }); + return std::vector(frames.size()); } } }