77#include < numeric>
88#include < atomic>
99#include < execinfo.h>
10+ #include < regex>
1011
1112#if __APPLE__
1213 #include < libkern/OSAtomic.h>
@@ -28,22 +29,46 @@ auto to_underlying (auto e)
2829 return static_cast <std::underlying_type_t <decltype (e)>> (e);
2930}
3031
31- inline std::string demangle (std::string name)
32+ inline std::string demangle (const std::string& name)
3233{
33- #if __has_include (<cxxabi.h>)
34+ #if __has_include(<cxxabi.h>)
3435 int status;
36+ std::unique_ptr<char , decltype (&std::free)> demangled (
37+ abi::__cxa_demangle (name.c_str (), nullptr , nullptr , &status),
38+ &std::free);
3539
36- if (char * demangled = abi::__cxa_demangle (name.c_str (), nullptr , nullptr , &status); status == 0 )
37- {
38- std::string demangledString (demangled);
39- free (demangled);
40- return demangledString;
41- }
40+ if (demangled && status == 0 )
41+ return std::string (demangled.get ());
4242 #endif
4343
4444 return name;
4545}
4646
47+ inline std::string extract_symbol (const std::string& line)
48+ {
49+ // macOS/BSD format: "frame binary address symbol + offset"
50+ if (line.find (" 0x" ) != std::string::npos)
51+ {
52+ std::regex macPattern (R"( ^\s*\d+\s+\S+\s+0x[0-9a-fA-F]+\s+(.+?)(?:\s+\+\s+\d+)?$)" );
53+ std::smatch match;
54+
55+ if (std::regex_match (line, match, macPattern))
56+ return match[1 ].str ();
57+ }
58+
59+ // Linux format: "binary(symbol+offset) [address]"
60+ {
61+ size_t lparen = line.find (' (' );
62+ size_t plus = line.find (' +' , lparen);
63+
64+ if (lparen != std::string::npos && plus != std::string::npos)
65+ return line.substr (lparen + 1 , plus - lparen - 1 );
66+ }
67+
68+ return line;
69+ }
70+
71+
4772inline std::string get_stacktrace ()
4873{
4974 std::string result;
@@ -53,7 +78,7 @@ inline std::string get_stacktrace()
5378 char ** frameStrings = backtrace_symbols (stack, frames);
5479
5580 for (auto i = (decltype (frames)) 0 ; i < frames; ++i)
56- (result.append (i, ' ' ) += demangle (frameStrings[i])) += " \n " ;
81+ (result.append (i, ' ' ) += demangle (extract_symbol ( frameStrings[i]) )) += " \n " ;
5782
5883 result += " \n " ;
5984 ::free (frameStrings);
0 commit comments