From a2cc7e8b0303d1a1c423994f477d5c9d181dd837 Mon Sep 17 00:00:00 2001 From: Patrick Lipka Date: Mon, 18 Aug 2025 18:43:48 +0200 Subject: [PATCH] fixiing segmentation fault --- src/rvprof_symbols.c | 22 ++++++++++++++++------ src/rvprof_timing.c | 25 ++++++++++++++++--------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/rvprof_symbols.c b/src/rvprof_symbols.c index 9606516..b60a20a 100644 --- a/src/rvprof_symbols.c +++ b/src/rvprof_symbols.c @@ -12,8 +12,7 @@ __thread char g_tmp_func_name[128]; static uintptr_t g_base_address_offset = 0; static int g_base_address_calculated = 0; - -// base address calculatiion +// base address calculation static void calculate_base_address_offset(void* known_runtime_addr, uintptr_t known_elf_addr){ if (g_base_address_calculated) return; @@ -53,6 +52,11 @@ static int add_symbol(uintptr_t addr, const char* name, size_t size){ // skip versioned symbols if (strstr(name, "@") != NULL) return 0; + // ensure capacity before accessing array + if (symbol_array_ensure_capacity(&g_rvprof.symbols, g_rvprof.symbols.size) < 0) { + return -1; + } + // add interesting symbols size_t name_len = strlen(name); char* tmp_name = rvprof_malloc(name_len+1); @@ -70,7 +74,7 @@ static int add_symbol(uintptr_t addr, const char* name, size_t size){ // ELF symbol parsing static int parse_elf_symbols(const char* filepath){ int fp = open(filepath, O_RDONLY); - if (fp< 0) return -1; + if (fp < 0) return -1; struct stat st; if (fstat(fp, &st) < 0){ @@ -78,7 +82,7 @@ static int parse_elf_symbols(const char* filepath){ return -1; } - // sanity check: file size, max fort executables defined here: 1 GiB + // sanity check: file size, max for executables defined here: 1 GiB if (st.st_size < (off_t)sizeof(Elf64_Ehdr) || st.st_size > 1024*1024*1024){ close(fp); return -1; @@ -87,7 +91,11 @@ static int parse_elf_symbols(const char* filepath){ void* mapped = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fp, 0); close(fp); - // check ELF magic with bounds checkuing + if (mapped == MAP_FAILED) { + return -1; + } + + // check ELF magic with bounds checking if (st.st_size < 16){ munmap(mapped, st.st_size); return -1; @@ -160,7 +168,6 @@ static int parse_elf_symbols(const char* filepath){ add_symbol(sym->st_value, name, sym->st_size); } - } } @@ -330,6 +337,9 @@ const char* rvprof_symbols_lookup(void* addr){ // public API rvprof_error_t rvprof_symbols_init(const char* program_path){ + // initialize symbols array first + memset(&g_rvprof.symbols, 0, sizeof(g_rvprof.symbols)); + // option 1: provided path if (program_path && parse_elf_symbols(program_path) == 0){ return RVPROF_SUCCESS; diff --git a/src/rvprof_timing.c b/src/rvprof_timing.c index 3871e2b..27de5fd 100644 --- a/src/rvprof_timing.c +++ b/src/rvprof_timing.c @@ -11,11 +11,14 @@ Maybe replace with a library call in the future // global flag for cycle counter availability static volatile int g_cycle_counter_available = 0; static volatile jmp_buf g_cycle_test_jmpbuf; +static volatile int g_signal_handler_active = 0; // signal handler for illegal instructions -static void sigkill_handler(int sig){ - g_cycle_counter_available = 0; - longjmp(g_cycle_test_jmpbuf, 1); +static void sigill_handler(int sig){ + if (g_signal_handler_active) { + g_cycle_counter_available = 0; + longjmp(g_cycle_test_jmpbuf, 1); + } } static inline uint64_t read_cycles(void){ @@ -24,8 +27,6 @@ static inline uint64_t read_cycles(void){ } uint64_t cycles; - - __asm__ volatile("csrr %0, cycle" : "=r"(cycles)); return cycles; } @@ -40,7 +41,7 @@ static inline uint64_t read_time_ns(void){ int rvprof_timing_test_cycle_counter(void){ // set up signal handler for illegal instruction struct sigaction old_action, new_action; - new_action.sa_handler = sigkill_handler; + new_action.sa_handler = sigill_handler; sigemptyset(&new_action.sa_mask); new_action.sa_flags = 0; @@ -50,6 +51,10 @@ int rvprof_timing_test_cycle_counter(void){ return 0; } + // initialize state + g_cycle_counter_available = 0; + g_signal_handler_active = 1; + // test cycle counter access if (setjmp(g_cycle_test_jmpbuf) == 0) { uint64_t cycles1, cycles2; @@ -66,11 +71,13 @@ int rvprof_timing_test_cycle_counter(void){ } else { g_cycle_counter_available = 0; } - }else{ - // illegal instruction occurred - g_cycle_counter_available = 0; + } else { + // illegal instruction occurred - handler already set g_cycle_counter_available = 0 } + // disable signal handler before restoring + g_signal_handler_active = 0; + // restore original signal handler sigaction(SIGILL, &old_action, NULL);