diff --git a/agent/native/ext/CMakeLists.txt b/agent/native/ext/CMakeLists.txt index ad36ca225..0ffbfbd4b 100644 --- a/agent/native/ext/CMakeLists.txt +++ b/agent/native/ext/CMakeLists.txt @@ -35,6 +35,13 @@ foreach(_php_version ${_supported_php_versions}) "PHP_ATOM_INC" "PHP_ABI=${CMAKE_C_COMPILER_ABI}") + if(MUSL_BUILD) + target_compile_definitions(${_Target} + PRIVATE + "__ELASTIC_LIBC_MUSL__" + ) + endif() + target_include_directories(${_Target} PUBLIC "${CONAN_INCLUDE_DIRS_PHP-HEADERS-${_php_version}}" "${CONAN_INCLUDE_DIRS_PHP-HEADERS-${_php_version}}/ext" "${CONAN_INCLUDE_DIRS_PHP-HEADERS-${_php_version}}/main" @@ -42,7 +49,6 @@ foreach(_php_version ${_supported_php_versions}) "${CONAN_INCLUDE_DIRS_PHP-HEADERS-${_php_version}}/Zend" "${CONAN_INCLUDE_DIRS_LIBCURL}" "${CONAN_INCLUDE_DIRS_LIBUNWIND}" - ) target_link_libraries(${_Target} diff --git a/agent/native/ext/platform.c b/agent/native/ext/platform.c index 50ba8b987..8d7a084a2 100644 --- a/agent/native/ext/platform.c +++ b/agent/native/ext/platform.c @@ -18,6 +18,7 @@ */ #include "platform.h" +#include "elastic_apm_version.h" #include #include #include @@ -36,6 +37,8 @@ # include # include # include +#define __USE_GNU +#include #endif #if defined( ELASTIC_APM_PLATFORM_HAS_LIBUNWIND ) @@ -378,30 +381,43 @@ void iterateOverCStackTraceLibUnwind( size_t numberOfFramesToSkip, IterateOverCS for (;; ++frameIndex) { // +1 is for this function frame - if ( frameIndex >= numberOfFramesToSkip + 1 ) - { - // https://www.nongnu.org/libunwind/man/unw_get_proc_name(3).html - int getProcNameRetVal = unw_get_proc_name( &unwindCursor, funcNameBuffer, funcNameBufferSize, &offsetInsideFunc ); + if ( frameIndex >= numberOfFramesToSkip + 1 ) { textOutputStreamRewind( &txtOutStream ); - switch ( getProcNameRetVal ) // https://www.nongnu.org/libunwind/man/unw_get_proc_name(3).html - { - case 0: // On successful completion, unw_get_proc_name() returns 0 - callback( streamPrintf( &txtOutStream, "%s + 0x%X", funcNameBuffer, (unsigned int)offsetInsideFunc ), callbackCtx ); - break; - case UNW_EUNSPEC: // An unspecified error occurred. - logErrorCallback( streamPrintf( &txtOutStream, "unw_get_proc_name call failed with return value UNW_EUNSPEC - stopping iteration over call stack" ), callbackCtx ); - return; - case UNW_ENOINFO: // Libunwind was unable to determine the name of the procedure. - callback( NULL, callbackCtx ); - break; - case UNW_ENOMEM: // The procedure name is too long to fit in the buffer provided. A truncated version of the name has been returned. - callback( streamPrintf( &txtOutStream, "%s (truncated) + 0x%X", funcNameBuffer, (unsigned int)offsetInsideFunc ), callbackCtx ); - break; - default: - logErrorCallback( streamPrintf( &txtOutStream, "unw_get_proc_name call failed with an unexpected return value (%d) - stopping iteration over call stack", getProcNameRetVal ), callbackCtx ); - return; + 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, + (void*)pi.start_ip - dlInfo.dli_fbase, + (void*)pi.start_ip - dlInfo.dli_fbase + offsetInsideFunc, + dlInfo.dli_fname ? dlInfo.dli_fname : "???", + (void*)pi.start_ip - 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 ) @@ -532,7 +548,13 @@ OsSignalHandler g_oldSignalHandler = NULL; void handleOsSignalLinux( int signalId ) { - ELASTIC_APM_LOG_FROM_CRASH_SIGNAL_HANDLER( "Received signal %d (%s)", signalId, osSignalIdToName( signalId ) ); +#ifdef __ELASTIC_LIBC_MUSL__ + #define LIBC_IMPL "musl" +#else + #define LIBC_IMPL "" +#endif + + ELASTIC_APM_LOG_FROM_CRASH_SIGNAL_HANDLER( "Received signal %d (%s). Agent version: " PHP_ELASTIC_APM_VERSION " " LIBC_IMPL, signalId, osSignalIdToName( signalId ) ); handleOsSignalLinux_writeStackTraceToSyslog(); /* Call the default signal handler to have core dump generated... */ diff --git a/agent/native/ext/unit_tests/CMakeLists.txt b/agent/native/ext/unit_tests/CMakeLists.txt index 829e51155..5e60c1685 100644 --- a/agent/native/ext/unit_tests/CMakeLists.txt +++ b/agent/native/ext/unit_tests/CMakeLists.txt @@ -111,6 +111,8 @@ LIST( APPEND source_files ${src_ext_dir}/time_util.h ${src_ext_dir}/time_util.c LIST( APPEND source_files ${src_ext_dir}/Tracer.h ${src_ext_dir}/Tracer.c ) LIST( APPEND source_files ${src_ext_dir}/Tracer.h ${src_ext_dir}/util.c ) +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++ -pthread -ldl") + IF ( NOT WIN32 ) ADD_LINK_OPTIONS( -rdynamic ) ENDIF()