in agent/native/ext/platform.cpp [364:439]
void iterateOverCStackTraceLibUnwind( size_t numberOfFramesToSkip, IterateOverCStackTraceCallback callback, IterateOverCStackTraceLogErrorCallback logErrorCallback, void* callbackCtx )
{
char txtOutStreamBuf[ ELASTIC_APM_TEXT_OUTPUT_STREAM_ON_STACK_BUFFER_SIZE ];
TextOutputStream txtOutStream = ELASTIC_APM_TEXT_OUTPUT_STREAM_FROM_STATIC_BUFFER( txtOutStreamBuf );
# define ELASTIC_APM_LIBUNWIND_CALL_RETURN_ON_ERROR( expr ) \
do { \
int temp_libUnwindRetVal = (expr); \
if ( temp_libUnwindRetVal < 0 ) \
{ \
textOutputStreamRewind( &txtOutStream ); \
logErrorCallback( streamPrintf( &txtOutStream, "%s call failed (return value: %d)", ELASTIC_APM_PP_STRINGIZE( expr ), temp_libUnwindRetVal ), callbackCtx ); \
return; \
} \
} while ( 0 )
unw_cursor_t unwindCursor;
unw_context_t unwindContext;
enum { funcNameBufferSize = 100 };
char funcNameBuffer[ funcNameBufferSize ];
unw_word_t offsetInsideFunc;
size_t frameIndex = 0;
ELASTIC_APM_LIBUNWIND_CALL_RETURN_ON_ERROR( unw_getcontext( &unwindContext ) );
ELASTIC_APM_LIBUNWIND_CALL_RETURN_ON_ERROR( unw_init_local( &unwindCursor, &unwindContext ) );
for (;; ++frameIndex)
{
// +1 is for this function frame
if ( frameIndex >= numberOfFramesToSkip + 1 ) {
textOutputStreamRewind( &txtOutStream );
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)) {
callback( streamPrintf( &txtOutStream,
"%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
), callbackCtx );
} else {
logErrorCallback( streamPrintf( &txtOutStream, "dladdr failed on frame %zu", frameIndex), callbackCtx );
}
} else {
logErrorCallback( streamPrintf( &txtOutStream, "unw_get_proc_info failed on frame %zu", frameIndex), callbackCtx );
}
}
int unwindStepRetVal = 0;
ELASTIC_APM_LIBUNWIND_CALL_RETURN_ON_ERROR( unwindStepRetVal = unw_step( &unwindCursor ) );
if ( unwindStepRetVal == 0 )
{
break;
}
}
# undef ELASTIC_APM_LIBUNWIND_CALL_RETURN_ON_ERROR
}