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()) {
|
if (nullptr != rawdump && !std::string(rawdump).empty()) {
|
||||||
return {rawdump};
|
return {rawdump};
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t max_dump_size = 50;
|
const size_t max_dump_size = 50;
|
||||||
void* dump[max_dump_size];
|
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
|
char** messages = backtrace_symbols(dump, static_cast<int>(size)); // overwrite sigaction with caller's address
|
||||||
|
|
||||||
// dump stack: skip first frame, since that is here
|
// dump stack: skip first frame, since that is here
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
for (size_t idx = 1; idx < size && messages != nullptr; ++idx) {
|
for (size_t idx = 1; idx < size && messages != nullptr; ++idx) {
|
||||||
char* mangled_name = 0, *offset_begin = 0, *offset_end = 0;
|
std::string strMessage{messages[idx]};
|
||||||
// find parentheses and +address offset surrounding mangled name
|
std::string mangled_name, offset;
|
||||||
for (char* p = messages[idx]; *p; ++p) {
|
|
||||||
if (*p == '(') {
|
/// first look for format that includes brackets "(mangled_name+offset)""
|
||||||
mangled_name = p;
|
const auto firstBracket = strMessage.find_last_of('(');
|
||||||
} else if (*p == '+') {
|
const auto secondBracket = strMessage.find_last_of(')');
|
||||||
offset_begin = p;
|
if (firstBracket != strMessage.npos && secondBracket != strMessage.npos)
|
||||||
} else if (*p == ')') {
|
{
|
||||||
offset_end = p;
|
const auto betweenBrackets = strMessage.substr(firstBracket + 1, secondBracket - firstBracket - 1);
|
||||||
break;
|
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 the line could be processed, attempt to demangle the symbol
|
||||||
if (mangled_name && offset_begin && offset_end &&
|
if (!mangled_name.empty() && !offset.empty()) {
|
||||||
mangled_name < offset_begin) {
|
|
||||||
*mangled_name++ = '\0';
|
|
||||||
*offset_begin++ = '\0';
|
|
||||||
*offset_end++ = '\0';
|
|
||||||
|
|
||||||
int status;
|
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 demangling is successful, output the demangled function name
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
oss << "\n\tstack dump [" << idx << "] " << messages[idx] << " : " << real_name << "+";
|
oss << "\tstack dump [" << idx << "] " << real_name << " + " << offset<< std::endl;
|
||||||
oss << offset_begin << offset_end << std::endl;
|
|
||||||
}// otherwise, output the mangled function name
|
}// otherwise, output the mangled function name
|
||||||
else {
|
else {
|
||||||
oss << "\tstack dump [" << idx << "] " << messages[idx] << mangled_name << "+";
|
oss << "\tstack dump [" << idx << "] " << mangled_name << " + " << offset<< std::endl;
|
||||||
oss << offset_begin << offset_end << std::endl;
|
|
||||||
}
|
}
|
||||||
free(real_name); // mallocated by abi::__cxa_demangle(...)
|
free(real_name); // mallocated by abi::__cxa_demangle(...)
|
||||||
} else {
|
} else {
|
||||||
// no demangling done -- just dump the whole line
|
// 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)
|
} // END: for(size_t idx = 1; idx < size && messages != nullptr; ++idx)
|
||||||
free(messages);
|
free(messages);
|
||||||
|
Loading…
Reference in New Issue
Block a user