From a0a16ea11ef82d9f9fa7a24c154c1c7fbfbf3cdd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 4 Aug 2026 18:51:01 -0700 Subject: [PATCH] fix eh_frame unwinder - switching to synchronous process reads exposed losing info about a missed address read for unwinding, so unwinds never succeeded --- src/eh_frame/unwind/eh_frame_unwind.c | 1 + src/eval_visualization/eval_visualization_core.c | 3 ++- src/linux/demon/linux_demon.c | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/eh_frame/unwind/eh_frame_unwind.c b/src/eh_frame/unwind/eh_frame_unwind.c index 0fedf232..47a5dba6 100644 --- a/src/eh_frame/unwind/eh_frame_unwind.c +++ b/src/eh_frame/unwind/eh_frame_unwind.c @@ -133,6 +133,7 @@ eh_uwnd_step(Arch arch, MemoryMap *memory_map, UWND_ModuleInfo *module_info, U64 // rjf: determine CIE's full address range Rng1U64 cie_vaddr_range = {0}; DW_Format cie_fmt = DW_Format_Null; + if(!done) { // rjf: read initial length data String8 initial_length_data = {0}; diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 35605bec..93287c5b 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1764,7 +1764,8 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) { ptr_data->addr_is_good = 1; } - else if(e_space_read(ptr_data->value_eval.space, &byte, &range_info, r1u64(ptr_data->value_eval.value.u64, ptr_data->value_eval.value.u64+1))) + else if(e_space_read(ptr_data->value_eval.space, &byte, &range_info, r1u64(ptr_data->value_eval.value.u64, ptr_data->value_eval.value.u64+1)) && + !(range_info.flags & E_SpaceRangeFlag_Stale)) { ptr_data->addr_is_good = !(byte_bad_flags & 1); } diff --git a/src/linux/demon/linux_demon.c b/src/linux/demon/linux_demon.c index 152e3951..4c85d7dc 100644 --- a/src/linux/demon/linux_demon.c +++ b/src/linux/demon/linux_demon.c @@ -690,7 +690,7 @@ lnx_dmn_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vbase, B32 is_rebased U64 bloom_word = (elf_class == ELF_Class_64) ? 8 : 4; U64 buckets_vaddr = dynamic_info.gnu_hash_vaddr + sizeof(gnu_header) + bloom_size * bloom_word; U64 chain_vaddr = buckets_vaddr + (U64)nbuckets * sizeof(U32); - + // find largest symbol index referenced by any bucket U32 max_bucket = 0; for(U32 b = 0; b < nbuckets; b += 1) @@ -702,7 +702,7 @@ lnx_dmn_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vbase, B32 is_rebased } if(entry > max_bucket) { max_bucket = entry; } } - + if(max_bucket < symoffset) { // no symbols in hash; total count is symoffset @@ -735,7 +735,7 @@ lnx_dmn_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vbase, B32 is_rebased } } } - + // scan symbol table for the rendezvous symbol if(dynamic_info.symtab_vaddr && dynamic_info.symtab_entry_size && symbol_count) {