From 783988c0ac5fd88c6b96ec812adb292f6a6bda87 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 7 Oct 2025 15:44:35 -0700 Subject: [PATCH] expand ctrl process memory cache access to allow waiting for fresh results, rather than any results; use when doing a ctrl process memory write, to prefer viewing less stale data on exact frame. also expand trap net generation with success bit, use to retry stepping commands across frames if process memory reads are hindered. abort after N retries. --- src/content/content.c | 16 ++---- src/ctrl/ctrl_core.c | 18 +++---- src/ctrl/ctrl_core.h | 4 +- src/dbg_engine/dbg_engine_core.c | 83 ++++++++++++++++++++------------ src/dbg_engine/dbg_engine_core.h | 17 +++++-- src/raddbg/raddbg_core.c | 16 +++--- src/raddbg/raddbg_views.c | 2 +- 7 files changed, 89 insertions(+), 67 deletions(-) diff --git a/src/content/content.c b/src/content/content.c index 09e4928a..8f353678 100644 --- a/src/content/content.c +++ b/src/content/content.c @@ -276,20 +276,12 @@ c_submit_data(C_Key key, Arena **data_arena, String8 data) // rjf: push hash into key's history if(key_node) { - U128 last_hash = {0}; - if(key_node->hash_history_gen >= 1) + if(key_node->hash_history_gen >= C_KEY_HASH_HISTORY_STRONG_REF_COUNT) { - last_hash = key_node->hash_history[(key_node->hash_history_gen-1)%ArrayCount(key_node->hash_history)]; - } - if(!u128_match(last_hash, hash)) - { - if(key_node->hash_history_gen >= C_KEY_HASH_HISTORY_STRONG_REF_COUNT) - { - key_expired_hash = key_node->hash_history[(key_node->hash_history_gen-C_KEY_HASH_HISTORY_STRONG_REF_COUNT)%ArrayCount(key_node->hash_history)]; - } - key_node->hash_history[key_node->hash_history_gen%ArrayCount(key_node->hash_history)] = hash; - key_node->hash_history_gen += 1; + key_expired_hash = key_node->hash_history[(key_node->hash_history_gen-C_KEY_HASH_HISTORY_STRONG_REF_COUNT)%ArrayCount(key_node->hash_history)]; } + key_node->hash_history[key_node->hash_history_gen%ArrayCount(key_node->hash_history)] = hash; + key_node->hash_history_gen += 1; } // rjf: key is new -> add this key to the associated root diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index cc702204..0879b0ca 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -6114,7 +6114,7 @@ ctrl_memory_artifact_destroy(AC_Artifact artifact) } internal C_Key -ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale) +ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, B32 wait_for_fresh, U64 endt_us, B32 *out_is_stale) { ProfBeginFunction(); struct @@ -6127,7 +6127,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 String8 key = str8_struct(&key_data); Access *access = access_open(); AC_Artifact artifact = ac_artifact_from_key(access, key, ctrl_memory_artifact_create, ctrl_memory_artifact_destroy, endt_us, - .flags = AC_Flag_HighPriority, + .flags = AC_Flag_HighPriority | (wait_for_fresh ? AC_Flag_WaitForFresh : 0), .gen = ctrl_mem_gen(), .slots_count = 2048, .stale_out = out_is_stale, @@ -6142,7 +6142,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 //- rjf: process memory reading helpers internal CTRL_ProcessMemorySlice -ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us) +ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, B32 wait_for_fresh, U64 endt_us) { ProfBeginFunction(); CTRL_ProcessMemorySlice result = {0}; @@ -6168,7 +6168,7 @@ ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rn { U64 page_base_vaddr = page_range.min + page_idx*page_size; B32 page_is_stale = 0; - C_Key page_key = ctrl_key_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0, endt_us, &page_is_stale); + C_Key page_key = ctrl_key_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0, wait_for_fresh, endt_us, &page_is_stale); U128 page_hash = c_hash_from_key(page_key, 0); U128 page_last_hash = c_hash_from_key(page_key, 1); result.stale = (result.stale || page_is_stale); @@ -6289,7 +6289,7 @@ ctrl_process_memory_read(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, { Temp scratch = scratch_begin(0, 0); U64 needed_size = dim_1u64(range); - CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process, range, endt_us); + CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process, range, 0, endt_us); B32 good = (slice.data.size >= needed_size && !slice.any_byte_bad); if(good) { @@ -6322,15 +6322,15 @@ ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src) // time. if(result) { - U64 endt_us = os_now_microseconds()+5000; + U64 endt_us = os_now_microseconds()+10000; U64 page_size = os_get_system_info()->page_size; // TODO(rjf): @page_size_from_process - Rng1U64 page_range = r1u64(range.min/page_size, range.max/page_size); + Rng1U64 page_range = r1u64(range.min/page_size, (range.max+page_size-1)/page_size); for EachInRange(page_idx, page_range) { Temp scratch = scratch_begin(0, 0); - ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process, r1u64(page_idx*page_size, (page_idx+1)*page_size), endt_us); + CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process, r1u64(page_idx*page_size, (page_idx+1)*page_size), 1, endt_us); scratch_end(scratch); - if(os_now_microseconds() >= endt_us) + if(!slice.stale || os_now_microseconds() >= endt_us) { break; } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 60e0729f..93ed7dc9 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -1004,10 +1004,10 @@ internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg); internal AC_Artifact ctrl_memory_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out); internal void ctrl_memory_artifact_destroy(AC_Artifact artifact); -internal C_Key ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale); +internal C_Key ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, B32 wait_for_fresh, U64 endt_us, B32 *out_is_stale); //- rjf: process memory reading helpers -internal CTRL_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us); +internal CTRL_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, B32 wait_for_fresh, U64 endt_us); internal B32 ctrl_process_memory_read(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us); #define ctrl_process_memory_read_struct(process, vaddr, is_stale_out, ptr, endt_us) ctrl_process_memory_read((process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us)) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 6643359e..afd632a9 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -290,11 +290,11 @@ d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams * // - for any instructions which may change the stack pointer, traps are placed // at them with the "save-stack-pointer | single-step-after" behaviors. -internal CTRL_TrapList +internal D_TrapNet d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread) { Temp scratch = scratch_begin(&arena, 1); - CTRL_TrapList result = {0}; + D_TrapNet result = {0}; // rjf: thread => unpacked info CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); @@ -305,13 +305,15 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread) String8 machine_code = {0}; { Rng1U64 rng = r1u64(ip_vaddr, ip_vaddr+max_instruction_size_from_arch(arch)); - CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, rng, os_now_microseconds()+5000); + CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, rng, 0, os_now_microseconds()+5000); machine_code = machine_code_slice.data; } // rjf: build traps if machine code was read successfully if(machine_code.size != 0) { + result.good = 1; + // rjf: decode instruction DASM_Inst inst = dasm_inst_from_code(scratch.arena, arch, ip_vaddr, machine_code, DASM_Syntax_Intel); @@ -319,7 +321,7 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread) if(inst.flags & DASM_InstFlag_Call || inst.flags & DASM_InstFlag_Repeats) { CTRL_Trap trap = {CTRL_TrapFlag_EndStepping, ip_vaddr+inst.size}; - ctrl_trap_list_push(arena, &result, &trap); + ctrl_trap_list_push(arena, &result.traps, &trap); } } @@ -327,12 +329,12 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread) return result; } -internal CTRL_TrapList +internal D_TrapNet d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread) { Temp scratch = scratch_begin(&arena, 1); log_infof("step_over_line:\n{\n"); - CTRL_TrapList result = {0}; + D_TrapNet result = {0}; // rjf: thread => info Arch arch = thread->arch; @@ -380,7 +382,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread) B32 good_machine_code = 0; if(good_line_info) { - CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, os_now_microseconds()+50000); + CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, 0, os_now_microseconds()+50000); machine_code = machine_code_slice.data; good_machine_code = (machine_code.size == dim_1u64(line_vaddr_rng) && !machine_code_slice.any_byte_bad); LogInfoNamedBlockF("machine_code_slice") @@ -469,7 +471,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread) if(add) { CTRL_Trap trap = {flags, trap_addr}; - ctrl_trap_list_push(arena, &result, &trap); + ctrl_trap_list_push(arena, &result.traps, &trap); } } @@ -477,11 +479,17 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread) if(good_line_info && good_machine_code) { CTRL_Trap trap = {CTRL_TrapFlag_EndStepping, line_vaddr_rng.max}; - ctrl_trap_list_push(arena, &result, &trap); + ctrl_trap_list_push(arena, &result.traps, &trap); + } + + // rjf: good if we got machine code + if(good_machine_code) + { + result.good = 1; } // rjf: log - LogInfoNamedBlockF("traps") for(CTRL_TrapNode *n = result.first; n != 0; n = n->next) + LogInfoNamedBlockF("traps") for(CTRL_TrapNode *n = result.traps.first; n != 0; n = n->next) { log_infof("{flags:0x%x, vaddr:0x%I64x}\n", n->v.flags, n->v.vaddr); } @@ -491,11 +499,11 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread) return result; } -internal CTRL_TrapList +internal D_TrapNet d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) { Temp scratch = scratch_begin(&arena, 1); - CTRL_TrapList result = {0}; + D_TrapNet result = {0}; // rjf: thread => info Arch arch = thread->arch; @@ -538,7 +546,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) B32 good_machine_code = 0; if(good_line_info) { - CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, os_now_microseconds()+5000); + CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, 0, os_now_microseconds()+5000); machine_code = machine_code_slice.data; good_machine_code = (machine_code.size == dim_1u64(line_vaddr_rng) && !machine_code_slice.any_byte_bad); } @@ -625,7 +633,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) if(add) { CTRL_Trap trap = {flags, trap_addr}; - ctrl_trap_list_push(arena, &result, &trap); + ctrl_trap_list_push(arena, &result.traps, &trap); } } @@ -633,7 +641,13 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread) if(good_line_info && good_machine_code) { CTRL_Trap trap = {CTRL_TrapFlag_EndStepping, line_vaddr_rng.max}; - ctrl_trap_list_push(arena, &result, &trap); + ctrl_trap_list_push(arena, &result.traps, &trap); + } + + // rjf: good if we got machine code + if(good_machine_code) + { + result.good = 1; } scratch_end(scratch); @@ -981,7 +995,7 @@ d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 U64 tls_index = 0; if(addr_size != 0) { - CTRL_ProcessMemorySlice tls_index_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, tls_vaddr_range, 0); + CTRL_ProcessMemorySlice tls_index_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, tls_vaddr_range, 0, 0); if(tls_index_slice.data.size >= addr_size) { tls_index = *(U64 *)tls_index_slice.data.str; @@ -994,13 +1008,13 @@ d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 U64 thread_info_addr = root_vaddr; U64 tls_addr_off = tls_index*addr_size; U64 tls_addr_array = 0; - CTRL_ProcessMemorySlice tls_addr_array_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(thread_info_addr, thread_info_addr+addr_size), 0); + CTRL_ProcessMemorySlice tls_addr_array_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(thread_info_addr, thread_info_addr+addr_size), 0, 0); String8 tls_addr_array_data = tls_addr_array_slice.data; if(tls_addr_array_data.size >= 8) { MemoryCopy(&tls_addr_array, tls_addr_array_data.str, sizeof(U64)); } - CTRL_ProcessMemorySlice result_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(tls_addr_array + tls_addr_off, tls_addr_array + tls_addr_off + addr_size), 0); + CTRL_ProcessMemorySlice result_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(tls_addr_array + tls_addr_off, tls_addr_array + tls_addr_off + addr_size), 0, 0); String8 result_data = result_slice.data; if(result_data.size >= 8) { @@ -1791,15 +1805,14 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P } else { - B32 good = 1; - CTRL_TrapList traps = {0}; + D_TrapNet trap_net = {0}; switch(cmd->kind) { default: break; - case D_CmdKind_StepIntoInst: {}break; - case D_CmdKind_StepOverInst: {traps = d_trap_net_from_thread__step_over_inst(scratch.arena, thread);}break; - case D_CmdKind_StepIntoLine: {traps = d_trap_net_from_thread__step_into_line(scratch.arena, thread);}break; - case D_CmdKind_StepOverLine: {traps = d_trap_net_from_thread__step_over_line(scratch.arena, thread);}break; + case D_CmdKind_StepIntoInst: {trap_net.good = 1;}break; + case D_CmdKind_StepOverInst: {trap_net = d_trap_net_from_thread__step_over_inst(scratch.arena, thread);}break; + case D_CmdKind_StepIntoLine: {trap_net = d_trap_net_from_thread__step_into_line(scratch.arena, thread);}break; + case D_CmdKind_StepOverLine: {trap_net = d_trap_net_from_thread__step_over_line(scratch.arena, thread);}break; case D_CmdKind_StepOut: { Access *access = access_open(); @@ -1812,32 +1825,42 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P { U64 vaddr = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[1]->regs); CTRL_Trap trap = {CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck, vaddr}; - ctrl_trap_list_push(scratch.arena, &traps, &trap); + ctrl_trap_list_push(scratch.arena, &trap_net.traps, &trap); + trap_net.good = 1; } else { log_user_error(str8_lit("Could not find the return address of the current callstack frame successfully.")); - good = 0; } access_close(access); }break; } - if(good && traps.count != 0) + if(trap_net.good && trap_net.traps.count != 0) { need_run = 1; run_kind = D_RunKind_Step; run_thread = thread; run_flags = 0; - run_traps = traps; + run_traps = trap_net.traps; } - if(good && traps.count == 0) + else if(trap_net.good && trap_net.traps.count == 0) { need_run = 1; run_kind = D_RunKind_SingleStep; run_thread = thread; run_flags = 0; - run_traps = traps; + run_traps = trap_net.traps; + } + else if(!trap_net.good && params->retry_idx < 1000) + { + D_CmdParams params_copy = *params; + params_copy.retry_idx += 1; + d_push_cmd(cmd->kind, ¶ms_copy); + } + else if(!trap_net.good) + { + log_user_error(str8_lit("Could not successfully step.")); } } }break; diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 1385e213..3748911b 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -69,6 +69,16 @@ struct D_PathMapArray U64 count; }; +//////////////////////////////// +//~ rjf: Trap Nets + +typedef struct D_TrapNet D_TrapNet; +struct D_TrapNet +{ + CTRL_TrapList traps; + B32 good; +}; + //////////////////////////////// //~ rjf: Tick Output Types @@ -187,6 +197,7 @@ struct D_CmdParams U32 pid; U32 rgba; D_TargetArray targets; + U64 retry_idx; }; typedef struct D_Cmd D_Cmd; @@ -358,9 +369,9 @@ internal void d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, //////////////////////////////// //~ rjf: Stepping "Trap Net" Builders -internal CTRL_TrapList d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread); -internal CTRL_TrapList d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread); -internal CTRL_TrapList d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread); +internal D_TrapNet d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread); +internal D_TrapNet d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread); +internal D_TrapNet d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread); //////////////////////////////// //~ rjf: Debug Info Lookups diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2c907bda..7a3bf34f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1805,7 +1805,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) default:{}break; case CTRL_EntityKind_Process: { - CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, entity->handle, range, rd_state->frame_eval_memread_endt_us); + CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, entity->handle, range, 0, rd_state->frame_eval_memread_endt_us); String8 data = slice.data; if(data.size == dim_1u64(range)) { @@ -2159,7 +2159,7 @@ rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated) CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); if(entity->kind == CTRL_EntityKind_Process) { - result = ctrl_key_from_process_vaddr_range(entity->handle, range, zero_terminated, 0, 0); + result = ctrl_key_from_process_vaddr_range(entity->handle, range, zero_terminated, 0, 0, 0); } }break; } @@ -4641,7 +4641,7 @@ rd_view_ui(Rng2F32 rect) CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(cell->eval.space); if(cell->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && space_entity->kind == CTRL_EntityKind_Process) { - CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, space_entity->handle, cell_vaddr_rng, rd_state->frame_eval_memread_endt_us); + CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, space_entity->handle, cell_vaddr_rng, 0, rd_state->frame_eval_memread_endt_us); for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1) { if(slice.byte_changed_flags[idx] != 0) @@ -5047,7 +5047,7 @@ rd_view_ui(Rng2F32 rect) cell->eval.space.kind == RD_EvalSpaceKind_CtrlEntity && row_info->callstack_thread == &ctrl_entity_nil && e_type_kind_from_key(cell->eval.irtree.type_key) != E_TypeKind_Function) - UI_FontSize(ui_top_font_size()*0.8f) + UI_FontSize(ui_top_font_size()*0.9f) { if(cell_width_px >= ui_top_font_size()*8.f) { @@ -7133,12 +7133,8 @@ rd_window_frame(void) ev_key_set_expansion(rd_view_eval_view(), ev_key_root(), ev_key_make(ev_hash_from_key(ev_key_root()), 1), 1); predicted_block_tree = ev_block_tree_from_eval(scratch.arena, rd_view_eval_view(), str8_zero(), hover_eval); } - F32 row_height_px = ui_top_px_height(); - U64 max_row_count = (U64)floor_f32(ui_top_font_size()*10.f / row_height_px); - if(ws->hover_eval_focused) - { - max_row_count *= 3; - } + F32 row_height_px = floor_f32(ui_top_font_size()*rd_setting_f32_from_name(str8_lit("row_height"))); + U64 max_row_count = 12; U64 needed_row_count = Min(max_row_count, predicted_block_tree.total_row_count); F32 width_px = floor_f32(70.f*ui_top_font_size()); F32 height_px = needed_row_count*row_height_px; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index f9684933..5dd6e0c4 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2973,7 +2973,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); if(entity->kind == CTRL_EntityKind_Process) { - CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, entity->handle, viz_range_bytes, 0); + CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, entity->handle, viz_range_bytes, 0, 0); visible_memory_change_flags = slice.byte_changed_flags; visible_memory_bad_flags = slice.byte_bad_flags; }