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 : #if defined(__GLIBC__) 19 0 : void * _map = NULL; 20 0 : int found = dladdr1( addr, &info, &_map, RTLD_DL_LINKMAP ); 21 0 : if( FD_LIKELY( found ) ) { 22 0 : struct link_map * map = _map; 23 0 : info.dli_fbase = (void*)map->l_addr; 24 0 : } 25 : #else 26 : int found = dladdr( addr, &info ); 27 : #endif 28 : 29 0 : if( FD_LIKELY( found && info.dli_fname && info.dli_fname[0]!='\0' ) ) { 30 0 : if( FD_UNLIKELY( !info.dli_sname ) ) info.dli_saddr = info.dli_fbase; 31 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 ); 32 0 : else { 33 0 : char sign; 34 0 : long offset; 35 0 : if( addr>=info.dli_saddr ) { sign = '+'; offset = (long)( (ulong)addr - (ulong)info.dli_saddr ); } 36 0 : else { sign = '-'; offset = (long)( (ulong)info.dli_saddr - (ulong)addr ); } 37 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 ); 38 0 : } 39 0 : } else { 40 0 : fd_log_private_fprintf_0( STDERR_FILENO, "%p\n", addr ); 41 0 : } 42 0 : } 43 0 : }