mirror of
https://github.com/KjellKod/g3log.git
synced 2024-12-12 10:23:50 +01:00
Parse OSX stack dump format in order to demangle it correctly (#473)
* Parse OSX format mangled stack trace correctly Co-authored-by: Grzegorz Glowacki <grzegorz.glowacki@avid.com>
This commit is contained in:
parent
16bb6f7e04
commit
09317e3573
@ -145,50 +145,57 @@ namespace g3 {
|
||||
if (nullptr != rawdump && !std::string(rawdump).empty()) {
|
||||
return {rawdump};
|
||||
}
|
||||
|
||||
const size_t max_dump_size = 50;
|
||||
void* dump[max_dump_size];
|
||||
size_t size = backtrace(dump, max_dump_size);
|
||||
const size_t size = backtrace(dump, max_dump_size);
|
||||
char** messages = backtrace_symbols(dump, static_cast<int>(size)); // overwrite sigaction with caller's address
|
||||
|
||||
// dump stack: skip first frame, since that is here
|
||||
std::ostringstream oss;
|
||||
for (size_t idx = 1; idx < size && messages != nullptr; ++idx) {
|
||||
char* mangled_name = 0, *offset_begin = 0, *offset_end = 0;
|
||||
// find parentheses and +address offset surrounding mangled name
|
||||
for (char* p = messages[idx]; *p; ++p) {
|
||||
if (*p == '(') {
|
||||
mangled_name = p;
|
||||
} else if (*p == '+') {
|
||||
offset_begin = p;
|
||||
} else if (*p == ')') {
|
||||
offset_end = p;
|
||||
break;
|
||||
std::string strMessage{messages[idx]};
|
||||
std::string mangled_name, offset;
|
||||
|
||||
/// first look for format that includes brackets "(mangled_name+offset)""
|
||||
const auto firstBracket = strMessage.find_last_of('(');
|
||||
const auto secondBracket = strMessage.find_last_of(')');
|
||||
if (firstBracket != strMessage.npos && secondBracket != strMessage.npos)
|
||||
{
|
||||
const auto betweenBrackets = strMessage.substr(firstBracket + 1, secondBracket - firstBracket - 1);
|
||||
const auto plusSign = betweenBrackets.find_first_of('+');
|
||||
if (plusSign != betweenBrackets.npos)
|
||||
{
|
||||
mangled_name = betweenBrackets.substr(0, plusSign);
|
||||
offset = betweenBrackets.substr(plusSign + 1, betweenBrackets.npos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/// we did not found brackets, looking for "_mangled_name + offset"
|
||||
const auto plusSign = strMessage.find_first_of('+');
|
||||
const auto lastUnderscore = strMessage.rfind(" _");
|
||||
if (plusSign != strMessage.npos && lastUnderscore != strMessage.npos)
|
||||
{
|
||||
mangled_name = strMessage.substr(lastUnderscore + 1, plusSign - lastUnderscore - 2);
|
||||
offset = strMessage.substr(plusSign + 2, strMessage.npos);
|
||||
}
|
||||
}
|
||||
|
||||
// if the line could be processed, attempt to demangle the symbol
|
||||
if (mangled_name && offset_begin && offset_end &&
|
||||
mangled_name < offset_begin) {
|
||||
*mangled_name++ = '\0';
|
||||
*offset_begin++ = '\0';
|
||||
*offset_end++ = '\0';
|
||||
|
||||
if (!mangled_name.empty() && !offset.empty()) {
|
||||
int status;
|
||||
char* real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
|
||||
char* real_name = abi::__cxa_demangle(mangled_name.c_str(), 0, 0, &status);
|
||||
// if demangling is successful, output the demangled function name
|
||||
if (status == 0) {
|
||||
oss << "\n\tstack dump [" << idx << "] " << messages[idx] << " : " << real_name << "+";
|
||||
oss << offset_begin << offset_end << std::endl;
|
||||
oss << "\tstack dump [" << idx << "] " << real_name << " + " << offset<< std::endl;
|
||||
}// otherwise, output the mangled function name
|
||||
else {
|
||||
oss << "\tstack dump [" << idx << "] " << messages[idx] << mangled_name << "+";
|
||||
oss << offset_begin << offset_end << std::endl;
|
||||
oss << "\tstack dump [" << idx << "] " << mangled_name << " + " << offset<< std::endl;
|
||||
}
|
||||
free(real_name); // mallocated by abi::__cxa_demangle(...)
|
||||
} else {
|
||||
// no demangling done -- just dump the whole line
|
||||
oss << "\tstack dump [" << idx << "] " << messages[idx] << std::endl;
|
||||
oss << "\tstack dump [" << idx << "] " << strMessage << std::endl;
|
||||
}
|
||||
} // END: for(size_t idx = 1; idx < size && messages != nullptr; ++idx)
|
||||
free(messages);
|
||||
|
Loading…
Reference in New Issue
Block a user