Check external symbols start with _Z before demangling

This commit is contained in:
Jeremy Rifkin 2025-02-13 23:39:05 -06:00
parent ce97e0004d
commit 457bc4b8a1
No known key found for this signature in database
GPG Key ID: 19AA8270105E8EB4
9 changed files with 16 additions and 17 deletions

View File

@ -62,7 +62,7 @@ namespace cpptrace {
try { try {
std::vector<stacktrace_frame> trace = detail::resolve_frames(frames); std::vector<stacktrace_frame> trace = detail::resolve_frames(frames);
for(auto& frame : trace) { for(auto& frame : trace) {
frame.symbol = detail::demangle(frame.symbol); frame.symbol = detail::demangle(frame.symbol, true);
} }
return {std::move(trace)}; return {std::move(trace)};
} catch(...) { // NOSONAR } catch(...) { // NOSONAR
@ -109,7 +109,7 @@ namespace cpptrace {
try { try {
std::vector<stacktrace_frame> trace = detail::resolve_frames(frames); std::vector<stacktrace_frame> trace = detail::resolve_frames(frames);
for(auto& frame : trace) { for(auto& frame : trace) {
frame.symbol = detail::demangle(frame.symbol); frame.symbol = detail::demangle(frame.symbol, true);
} }
return {std::move(trace)}; return {std::move(trace)};
} catch(...) { // NOSONAR } catch(...) { // NOSONAR
@ -312,7 +312,7 @@ namespace cpptrace {
std::vector<frame_ptr> frames = detail::capture_frames(skip + 1, max_depth); std::vector<frame_ptr> frames = detail::capture_frames(skip + 1, max_depth);
std::vector<stacktrace_frame> trace = detail::resolve_frames(frames); std::vector<stacktrace_frame> trace = detail::resolve_frames(frames);
for(auto& frame : trace) { for(auto& frame : trace) {
frame.symbol = detail::demangle(frame.symbol); frame.symbol = detail::demangle(frame.symbol, true);
} }
return {std::move(trace)}; return {std::move(trace)};
} catch(...) { // NOSONAR } catch(...) { // NOSONAR

View File

@ -107,7 +107,7 @@ CTRACE_FORMAT_EPILOGUE
new_frame.line = frame.line.value_or(invalid_pos); new_frame.line = frame.line.value_or(invalid_pos);
new_frame.column = frame.column.value_or(invalid_pos); new_frame.column = frame.column.value_or(invalid_pos);
new_frame.filename = generate_owning_string(frame.filename).data; new_frame.filename = generate_owning_string(frame.filename).data;
new_frame.symbol = generate_owning_string(cpptrace::detail::demangle(frame.symbol)).data; new_frame.symbol = generate_owning_string(cpptrace::detail::demangle(frame.symbol, true)).data;
new_frame.is_inline = ctrace_bool(frame.is_inline); new_frame.is_inline = ctrace_bool(frame.is_inline);
return new_frame; return new_frame;
} }

View File

@ -5,7 +5,7 @@
namespace cpptrace { namespace cpptrace {
namespace detail { namespace detail {
std::string demangle(const std::string&); std::string demangle(const std::string& name, bool check_prefix);
} }
} }

View File

@ -13,13 +13,12 @@
namespace cpptrace { namespace cpptrace {
namespace detail { namespace detail {
std::string demangle(const std::string& name) { std::string demangle(const std::string& name, bool check_prefix) {
// TODO: Do a special check to ensure external names start with _Z? // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#demangler
// // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#demangler // Check both _Z and __Z, apple prefixes all symbols with an underscore
// // check both _Z and __Z, apple prefixes all symbols with an underscore if(check_prefix && !(starts_with(name, "_Z") || starts_with(name, "__Z"))) {
// if(!(starts_with(name, "_Z") || starts_with(name, "__Z"))) { return name;
// return name; }
// }
// Apple clang demangles __Z just fine but gcc doesn't, so just offset the leading underscore // Apple clang demangles __Z just fine but gcc doesn't, so just offset the leading underscore
std::size_t offset = 0; std::size_t offset = 0;
if(starts_with(name, "__Z")) { if(starts_with(name, "__Z")) {

View File

@ -6,7 +6,7 @@
namespace cpptrace { namespace cpptrace {
namespace detail { namespace detail {
std::string demangle(const std::string& name) { std::string demangle(const std::string& name, bool) {
return name; return name;
} }
} }

View File

@ -12,7 +12,7 @@
namespace cpptrace { namespace cpptrace {
namespace detail { namespace detail {
std::string demangle(const std::string& name) { std::string demangle(const std::string& name, bool) {
char buffer[500]; char buffer[500];
auto ret = UnDecorateSymbolName(name.c_str(), buffer, sizeof(buffer) - 1, 0); auto ret = UnDecorateSymbolName(name.c_str(), buffer, sizeof(buffer) - 1, 0);
if(ret == 0) { if(ret == 0) {

View File

@ -17,7 +17,7 @@ namespace detail {
inline std::string exception_type_name() { inline std::string exception_type_name() {
#if defined(CPPTRACE_HAS_CXX_EXCEPTION_TYPE) && (IS_LIBSTDCXX || IS_LIBCXX) #if defined(CPPTRACE_HAS_CXX_EXCEPTION_TYPE) && (IS_LIBSTDCXX || IS_LIBCXX)
const std::type_info* t = abi::__cxa_current_exception_type(); const std::type_info* t = abi::__cxa_current_exception_type();
return t ? detail::demangle(t->name()) : "<unknown>"; return t ? detail::demangle(t->name(), false) : "<unknown>";
#else #else
return "<unknown>"; return "<unknown>";
#endif #endif

View File

@ -12,7 +12,7 @@
namespace cpptrace { namespace cpptrace {
std::string demangle(const std::string& name) { std::string demangle(const std::string& name) {
return detail::demangle(name); return detail::demangle(name, false);
} }
std::string get_snippet(const std::string& path, std::size_t line, std::size_t context_size, bool color) { std::string get_snippet(const std::string& path, std::size_t line, std::size_t context_size, bool color) {

View File

@ -26,7 +26,7 @@ void resolve(const std::filesystem::path& path, cpptrace::frame_ptr address) {
if(trace.size() != 1) { if(trace.size() != 1) {
throw std::runtime_error("Something went wrong, trace vector size didn't match"); throw std::runtime_error("Something went wrong, trace vector size didn't match");
} }
trace[0].symbol = cpptrace::detail::demangle(trace[0].symbol); trace[0].symbol = cpptrace::demangle(trace[0].symbol);
formatter.print(trace[0]); formatter.print(trace[0]);
std::cout<<std::endl; std::cout<<std::endl;
} }