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

View File

@ -107,7 +107,7 @@ CTRACE_FORMAT_EPILOGUE
new_frame.line = frame.line.value_or(invalid_pos);
new_frame.column = frame.column.value_or(invalid_pos);
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);
return new_frame;
}

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@ namespace detail {
inline std::string exception_type_name() {
#if defined(CPPTRACE_HAS_CXX_EXCEPTION_TYPE) && (IS_LIBSTDCXX || IS_LIBCXX)
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
return "<unknown>";
#endif

View File

@ -12,7 +12,7 @@
namespace cpptrace {
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) {

View File

@ -26,7 +26,7 @@ void resolve(const std::filesystem::path& path, cpptrace::frame_ptr address) {
if(trace.size() != 1) {
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]);
std::cout<<std::endl;
}