diff --git a/src/demangle/demangle_with_cxxabi.cpp b/src/demangle/demangle_with_cxxabi.cpp index 15dfb63..6f90265 100644 --- a/src/demangle/demangle_with_cxxabi.cpp +++ b/src/demangle/demangle_with_cxxabi.cpp @@ -2,6 +2,8 @@ #include "demangle/demangle.hpp" +#include "utils/utils.hpp" + #include #include @@ -11,6 +13,11 @@ namespace cpptrace { namespace detail { std::string demangle(const std::string& name) { int status; + // 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; + } // presumably thread-safe // it appears safe to pass nullptr for status however the docs don't explicitly say it's safe so I don't // want to rely on it diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp index b546246..e074b5b 100644 --- a/src/utils/utils.hpp +++ b/src/utils/utils.hpp @@ -83,6 +83,10 @@ namespace detail { return str.substr(left, right - left); } + inline bool starts_with(const std::string& str, const std::string& prefix) { + return str.size() >= prefix.size() && str.compare(0, prefix.size(), prefix) == 0; + } + inline bool is_little_endian() { std::uint16_t num = 0x1; const auto* ptr = (std::uint8_t*)# diff --git a/test/unit/internals/string_utils.cpp b/test/unit/internals/string_utils.cpp index 49a0dad..6f16aa5 100644 --- a/test/unit/internals/string_utils.cpp +++ b/test/unit/internals/string_utils.cpp @@ -9,6 +9,7 @@ using testing::ElementsAre; using cpptrace::detail::split; using cpptrace::detail::join; using cpptrace::detail::trim; +using cpptrace::detail::starts_with; namespace { @@ -77,4 +78,15 @@ TEST(TrimTest, Basic) { EXPECT_EQ(trim("\t test\n "), "test"); } +TEST(StartsWith, Basic) { + EXPECT_TRUE(starts_with("", "")); + EXPECT_TRUE(starts_with("abc", "")); + EXPECT_FALSE(starts_with("", "abc")); + EXPECT_FALSE(starts_with("ab", "abc")); + EXPECT_TRUE(starts_with("test", "test")); + EXPECT_TRUE(starts_with("hello_world", "hello")); + EXPECT_FALSE(starts_with("hello_world", "world")); + EXPECT_FALSE(starts_with("abcd", "abce")); +} + }