in prod/native/libcommon/code/os/StackTraceCapture.cpp [34:84]
std::string getStackTrace(size_t numberOfFramesToSkip) {
unw_cursor_t unwindCursor;
unw_context_t unwindContext;
constexpr size_t funcNameBufferSize = 100;
char funcNameBuffer[funcNameBufferSize];
unw_word_t offsetInsideFunc;
if (unw_getcontext(&unwindContext) < 0) {
return {};
}
if (unw_init_local(&unwindCursor, &unwindContext) < 0) {
return {};
}
std::string output;
for (size_t frameIndex = 0;; ++frameIndex) {
// +1 is for this function frame
if (frameIndex >= numberOfFramesToSkip + 1) {
unw_proc_info_t pi;
if (unw_get_proc_info(&unwindCursor, &pi) == 0) {
*funcNameBuffer = 0;
offsetInsideFunc = 0;
int getProcNameRetVal = unw_get_proc_name(&unwindCursor, funcNameBuffer, funcNameBufferSize, &offsetInsideFunc);
if (getProcNameRetVal != UNW_ESUCCESS && getProcNameRetVal != -UNW_ENOMEM) {
strcpy(funcNameBuffer, "???");
unw_word_t pc;
unw_get_reg(&unwindCursor, UNW_REG_IP, &pc);
offsetInsideFunc = pc - pi.start_ip;
}
Dl_info dlInfo;
if (dladdr((const void *)pi.gp, &dlInfo)) {
output.append(elasticapm::utils::stringPrintf("%s(%s+0x%lx) ModuleBase: %p FuncStart: 0x%lx FuncEnd: 0x%lx FuncStartRelative: 0x%lx FuncOffsetRelative: 0x%lx\n\t'addr2line -afCp -e \"%s\" %lx'\n", dlInfo.dli_fname ? dlInfo.dli_fname : "???", dlInfo.dli_sname ? dlInfo.dli_sname : funcNameBuffer, offsetInsideFunc, dlInfo.dli_fbase, pi.start_ip, pi.end_ip, pi.start_ip - reinterpret_cast<unw_word_t>(dlInfo.dli_fbase), pi.start_ip - reinterpret_cast<unw_word_t>(dlInfo.dli_fbase) + offsetInsideFunc, dlInfo.dli_fname ? dlInfo.dli_fname : "???", pi.start_ip - reinterpret_cast<unw_word_t>(dlInfo.dli_fbase) + offsetInsideFunc));
} else {
output.append(elasticapm::utils::stringPrintf("dladdr failed on frame %zu\n", frameIndex));
}
} else {
output.append(elasticapm::utils::stringPrintf("unw_get_proc_info failed on frame %zu", frameIndex));
}
}
int unwindStepRetVal = 0;
unwindStepRetVal = unw_step(&unwindCursor);
if (unwindStepRetVal < 0) {
return output;
} else if (unwindStepRetVal == 0) {
break;
}
}
return output;
}