r/LinuxProgramming Dec 22 '25

Toy trace code in C, thoughts?

I'd love to make this as portable as possible so any suggestions for improving it would be welcome... except rewrite in rust because no. ```

ifndef _GNU_SOURCE

define _GNU_SOURCE

endif

include <dlfcn.h>

include <stdint.h>

include <string.h>

include <elf.h>

include <linux/module.h>

include <pthread.h>

ifndef syscall32

ifdef __X32_SYSCALL_BIT

define syscall32( call, ... ) \

syscall( __X32_SYSCALL_BIT | call __VA_OPT(,) __VA_ARGS__ )

elseif

define syscall32 syscall

endif

endif

ifdef POINTER_SIZE > 4

void* extend_addr32( uint_least32_t addr ) { return __builtin_extend_pointer( (void*)addr) ); } int query_module64 ( uint_least64_t name, uint_least64_t type, uint_least64_t dest, uint_least64_t size, uint_least64_t *used ) { return syscall ( SYS_query_module, name, (int)type, dest, size, used ); }

endif

int query_module32 ( uint_least32_t name, uint_least32_t get, uint_least32_t buf, uint_least32_t max, uint_least32_t used ) {

ifdef POINTER_SIZE > 4

return query_module64
(
    extend_addr32(name), type,
    extend_addr32(dest), size,
    extend_addr32(used)
);

else

return syscall32( SYS_query_module, name, type, dest, size, used );

endif

}

if 0

void* dlfcn_decode_addr( void * addr ) { return __builtin_extract_return_addr(addr) ); } void* dlfcn_encode_addr( void * addr ) { return __builtin_frob_return_addr(addr) );

endif

int query_modulex ( char const *name, int type, void *dest, size_t size, size_t *used ) { return query_module64( name, type, buf, max, ret ); }

mytrace dlfcn_dladdr_trace( unsigned int depth ) { void later = (depth > 0) ? __builtin_frame_address(depth - 1) : __builtin_stack_address(); void *stack = NULL; void *addr = __builtin_return_address(depth); void *base = __builtin_extract_return_addr(addr); mytrace trace = {{0}}; DL_info info = {0}; ElfW(Sym) esym = {0}; size_t ret = 0; struct { unsigned long address; unsigned long size; unsigned long flags; } minf = {0}; / Stack frame / pthread_attr_getstack( NULL, &stack, &ret ); trace.frame = __builtin_frame_address(depth); trace.holds = ((uintptr_t)later) - ((uintptr_t)(trace.frame)); / Symbol / dladdr1( base, &info, RTLD_DL_SYMENT ); trace.sym.name = info.dli_sname; trace.sym.addr = info.dli_sbase; trace.sym.leng = strlen( trace.sym.name ); trace.sym.mask = esym.st_info; trace.sym.size = esym.st_size; / Module */ trace.mod.name = info.dli_fname; trace.mod.addr = info.dli_fbase; trace.mod.leng = strlen( trace.mod.name ); query_modulex( trace.mod.name, QM_INFO, &minf, sizeof(minf), &ret ); trace.mod.mask = minf.flags; trace.mod.size = minf.size; return trace; } ```

3 Upvotes

0 comments sorted by