Line data Source code
1 : #define _GNU_SOURCE 2 : #include "fd_backtrace.h" 3 : #include "../fd_util_base.h" 4 : #include "../log/fd_log.h" 5 : 6 : #include <unistd.h> 7 : #include <string.h> 8 : #include <dlfcn.h> 9 : #include <link.h> 10 : 11 : void 12 : fd_backtrace_log( void ** addrs, 13 0 : ulong addrs_cnt ) { 14 0 : for( ulong i=0UL; i<addrs_cnt; i++ ) { 15 0 : void * addr = addrs[ i ]; 16 0 : Dl_info info; 17 : 18 0 : void * _map = NULL; 19 0 : if( FD_LIKELY( dladdr1( addr, &info, &_map, RTLD_DL_LINKMAP ) && info.dli_fname && info.dli_fname[0]!='\0' ) ) { 20 0 : struct link_map * map = _map; 21 0 : info.dli_fbase = (void*)map->l_addr; 22 0 : if( FD_UNLIKELY( !info.dli_sname ) ) info.dli_saddr = info.dli_fbase; 23 0 : if( FD_UNLIKELY( !info.dli_sname && !info.dli_saddr ) ) fd_log_private_fprintf_0( STDERR_FILENO, "%s(%s) [%p]\n", info.dli_fname ? info.dli_fname : "", info.dli_sname ? info.dli_sname : "", addr ); 24 0 : else { 25 0 : char sign; 26 0 : long offset; 27 0 : if( addr>=info.dli_saddr ) { sign = '+'; offset = (long)( (ulong)addr - (ulong)info.dli_saddr ); } 28 0 : else { sign = '-'; offset = (long)( (ulong)info.dli_saddr - (ulong)addr ); } 29 0 : fd_log_private_fprintf_0( STDERR_FILENO, "%s(%s%c%#lx) [%p]\n", info.dli_fname ? info.dli_fname : "", info.dli_sname ? info.dli_sname : "", sign, (ulong)offset, addr ); 30 0 : } 31 0 : } else { 32 : fd_log_private_fprintf_0( STDERR_FILENO, "%p\n", addr ); 33 0 : } 34 0 : } 35 0 : }