mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-23 12:15:00 -07:00
sketch out unwind cache
This commit is contained in:
+55
-71
@@ -1084,7 +1084,7 @@ internal CTRL_Entity *
|
||||
ctrl_module_from_thread_candidates(CTRL_EntityStore *store, CTRL_Entity *thread, CTRL_EntityList *candidates)
|
||||
{
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
|
||||
U64 thread_rip_vaddr = ctrl_query_cached_rip_from_thread(store, thread->handle);
|
||||
U64 thread_rip_vaddr = ctrl_rip_from_thread(store, thread->handle);
|
||||
CTRL_Entity *src_module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr);
|
||||
CTRL_Entity *module = &ctrl_entity_nil;
|
||||
for(CTRL_EntityNode *n = candidates->first; n != 0; n = n->next)
|
||||
@@ -1266,7 +1266,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list)
|
||||
}
|
||||
}
|
||||
thread->stack_base = event->stack_base;
|
||||
ctrl_query_cached_rip_from_thread(store, event->entity);
|
||||
ctrl_rip_from_thread(store, event->entity);
|
||||
}break;
|
||||
case CTRL_EventKind_EndThread:
|
||||
{
|
||||
@@ -1432,6 +1432,15 @@ ctrl_init(void)
|
||||
ctrl_state->thread_reg_cache.stripes[idx].arena = arena_alloc();
|
||||
ctrl_state->thread_reg_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc();
|
||||
}
|
||||
ctrl_state->thread_unwind_cache.slots_count = 1024;
|
||||
ctrl_state->thread_unwind_cache.slots = push_array(arena, CTRL_ThreadUnwindCacheSlot, ctrl_state->thread_unwind_cache.slots_count);
|
||||
ctrl_state->thread_unwind_cache.stripes_count = os_get_system_info()->logical_processor_count;
|
||||
ctrl_state->thread_unwind_cache.stripes = push_array(arena, CTRL_ThreadUnwindCacheStripe, ctrl_state->thread_unwind_cache.stripes_count);
|
||||
for(U64 idx = 0; idx < ctrl_state->thread_unwind_cache.stripes_count; idx += 1)
|
||||
{
|
||||
ctrl_state->thread_unwind_cache.stripes[idx].arena = arena_alloc();
|
||||
ctrl_state->thread_unwind_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc();
|
||||
}
|
||||
ctrl_state->module_image_info_cache.slots_count = 1024;
|
||||
ctrl_state->module_image_info_cache.slots = push_array(arena, CTRL_ModuleImageInfoCacheSlot, ctrl_state->module_image_info_cache.slots_count);
|
||||
ctrl_state->module_image_info_cache.stripes_count = os_get_system_info()->logical_processor_count;
|
||||
@@ -1686,7 +1695,7 @@ ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range,
|
||||
//- rjf: process memory cache reading helpers
|
||||
|
||||
internal CTRL_ProcessMemorySlice
|
||||
ctrl_query_cached_data_from_process_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, U64 endt_us)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
CTRL_ProcessMemorySlice result = {0};
|
||||
@@ -1829,37 +1838,12 @@ ctrl_query_cached_data_from_process_vaddr_range(Arena *arena, CTRL_Handle proces
|
||||
return result;
|
||||
}
|
||||
|
||||
internal CTRL_ProcessMemorySlice
|
||||
ctrl_query_cached_zero_terminated_data_from_process_vaddr_limit(Arena *arena, CTRL_Handle process, U64 vaddr, U64 limit, U64 element_size, U64 endt_us)
|
||||
{
|
||||
CTRL_ProcessMemorySlice result = ctrl_query_cached_data_from_process_vaddr_range(arena, process, r1u64(vaddr, vaddr+limit), endt_us);
|
||||
U64 element_count = result.data.size/element_size;
|
||||
for(U64 element_idx = 0; element_idx < element_count; element_idx += 1)
|
||||
{
|
||||
B32 element_is_zero = 1;
|
||||
for(U64 element_byte_idx = 0; element_byte_idx < element_size; element_byte_idx += 1)
|
||||
{
|
||||
if(result.data.str[element_idx*element_size + element_byte_idx] != 0)
|
||||
{
|
||||
element_is_zero = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(element_is_zero)
|
||||
{
|
||||
result.data.size = element_idx*element_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
ctrl_read_cached_process_memory(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us)
|
||||
ctrl_process_memory_read(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U64 needed_size = dim_1u64(range);
|
||||
CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process, range, endt_us);
|
||||
CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process, range, endt_us);
|
||||
B32 good = (slice.data.size >= needed_size && !slice.any_byte_bad);
|
||||
if(good)
|
||||
{
|
||||
@@ -1932,7 +1916,7 @@ ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src)
|
||||
for(Task *task = first_task; task != 0; task = task->next)
|
||||
{
|
||||
Temp temp = temp_begin(scratch.arena);
|
||||
ctrl_query_cached_data_from_process_vaddr_range(temp.arena, task->process, task->range, endt_us);
|
||||
ctrl_process_memory_slice_from_vaddr_range(temp.arena, task->process, task->range, endt_us);
|
||||
temp_end(temp);
|
||||
}
|
||||
|
||||
@@ -1949,7 +1933,7 @@ ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src)
|
||||
//- rjf: thread register cache reading
|
||||
|
||||
internal void *
|
||||
ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle)
|
||||
ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle)
|
||||
{
|
||||
CTRL_ThreadRegCache *cache = &ctrl_state->thread_reg_cache;
|
||||
CTRL_Entity *thread_entity = ctrl_entity_from_handle(store, handle);
|
||||
@@ -2008,31 +1992,31 @@ ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, C
|
||||
}
|
||||
|
||||
internal U64
|
||||
ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle)
|
||||
ctrl_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle)
|
||||
{
|
||||
U64 result = dmn_tls_root_vaddr_from_thread(handle.dmn_handle);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle)
|
||||
ctrl_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
CTRL_Entity *thread_entity = ctrl_entity_from_handle(store, handle);
|
||||
Arch arch = thread_entity->arch;
|
||||
void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, store, handle);
|
||||
void *block = ctrl_reg_block_from_thread(scratch.arena, store, handle);
|
||||
U64 result = regs_rip_from_arch_block(arch, block);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
ctrl_query_cached_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle)
|
||||
ctrl_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
CTRL_Entity *thread_entity = ctrl_entity_from_handle(store, handle);
|
||||
Arch arch = thread_entity->arch;
|
||||
void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, store, handle);
|
||||
void *block = ctrl_reg_block_from_thread(scratch.arena, store, handle);
|
||||
U64 result = regs_rsp_from_arch_block(arch, block);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
@@ -2294,7 +2278,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
U8 inst[4] = {0};
|
||||
if(read_vaddr + sizeof(inst) <= read_vaddr_opl)
|
||||
{
|
||||
inst_good = ctrl_read_cached_process_memory(process_handle, r1u64(read_vaddr, read_vaddr+sizeof(inst)), &is_stale, inst, endt_us);
|
||||
inst_good = ctrl_process_memory_read(process_handle, r1u64(read_vaddr, read_vaddr+sizeof(inst)), &is_stale, inst, endt_us);
|
||||
inst_good = inst_good && !is_stale;
|
||||
}
|
||||
if(!inst_good)
|
||||
@@ -2375,7 +2359,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
U8 inst_byte = 0;
|
||||
if(read_vaddr + sizeof(inst_byte) <= read_vaddr_opl)
|
||||
{
|
||||
inst_byte_good = ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us);
|
||||
inst_byte_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us);
|
||||
}
|
||||
if(!inst_byte_good || is_stale)
|
||||
{
|
||||
@@ -2391,7 +2375,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
check_vaddr = read_vaddr + 1;
|
||||
if(read_vaddr + sizeof(check_inst_byte) <= read_vaddr_opl)
|
||||
{
|
||||
check_inst_byte_good = ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &check_inst_byte, endt_us);
|
||||
check_inst_byte_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &check_inst_byte, endt_us);
|
||||
}
|
||||
if(!check_inst_byte_good || is_stale)
|
||||
{
|
||||
@@ -2427,7 +2411,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
B32 imm_good = 0;
|
||||
if(read_vaddr + sizeof(imm) <= read_vaddr_opl)
|
||||
{
|
||||
imm_good = ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us);
|
||||
imm_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us);
|
||||
}
|
||||
if(!imm_good || is_stale)
|
||||
{
|
||||
@@ -2456,7 +2440,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
B32 next_inst_byte_good = 0;
|
||||
if(read_vaddr + sizeof(next_inst_byte) <= read_vaddr_opl)
|
||||
{
|
||||
next_inst_byte_good = ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &next_inst_byte, endt_us);
|
||||
next_inst_byte_good = ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &next_inst_byte, endt_us);
|
||||
}
|
||||
if(next_inst_byte_good)
|
||||
{
|
||||
@@ -2485,7 +2469,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
|
||||
//- rjf: read next instruction byte
|
||||
U8 inst_byte = 0;
|
||||
is_good = is_good && ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us);
|
||||
is_good = is_good && ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us);
|
||||
is_good = is_good && !is_stale;
|
||||
read_vaddr += 1;
|
||||
|
||||
@@ -2494,7 +2478,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
if((inst_byte & 0xF0) == 0x40)
|
||||
{
|
||||
rex = inst_byte & 0xF; // rex prefix
|
||||
is_good = is_good && ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us);
|
||||
is_good = is_good && ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &inst_byte, endt_us);
|
||||
is_good = is_good && !is_stale;
|
||||
read_vaddr += 1;
|
||||
}
|
||||
@@ -2515,7 +2499,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
// rjf: read value at rsp
|
||||
U64 sp = regs->rsp.u64;
|
||||
U64 value = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, sp, &is_stale, &value, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, sp, &is_stale, &value, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -2540,7 +2524,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
|
||||
// rjf: read the 4-byte immediate
|
||||
S32 imm = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -2563,7 +2547,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
|
||||
// rjf: read the 4-byte immediate
|
||||
S8 imm = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -2583,7 +2567,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
{
|
||||
// rjf: read source register
|
||||
U8 modrm = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &modrm, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &modrm, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -2601,7 +2585,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
if((modrm >> 6) == 1)
|
||||
{
|
||||
S8 imm8 = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm8, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm8, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -2614,7 +2598,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
// rjf: read 4-byte immediate
|
||||
else
|
||||
{
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -2637,7 +2621,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
// rjf: read new ip
|
||||
U64 sp = regs->rsp.u64;
|
||||
U64 new_ip = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, sp, &is_stale, &new_ip, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, sp, &is_stale, &new_ip, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -2646,7 +2630,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
|
||||
// rjf: read 2-byte immediate & advance stack pointer
|
||||
U16 imm = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, read_vaddr, &is_stale, &imm, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -2669,7 +2653,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
// rjf: read new ip
|
||||
U64 sp = regs->rsp.u64;
|
||||
U64 new_ip = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, sp, &is_stale, &new_ip, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, sp, &is_stale, &new_ip, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -2716,7 +2700,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
{
|
||||
U64 unwind_info_off = first_pdata->voff_unwind_info;
|
||||
PE_UnwindInfo unwind_info = {0};
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -2740,11 +2724,11 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
B32 good_unwind_info = 1;
|
||||
U64 unwind_info_off = pdata->voff_unwind_info;
|
||||
PE_UnwindInfo unwind_info = {0};
|
||||
good_unwind_info = good_unwind_info && ctrl_read_cached_process_memory_struct(process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us);
|
||||
good_unwind_info = good_unwind_info && ctrl_process_memory_read_struct(process->handle, module->vaddr_range.min+unwind_info_off, &is_stale, &unwind_info, endt_us);
|
||||
PE_UnwindCode *unwind_codes = push_array(scratch.arena, PE_UnwindCode, unwind_info.codes_num);
|
||||
good_unwind_info = good_unwind_info && ctrl_read_cached_process_memory(process->handle, r1u64(module->vaddr_range.min+unwind_info_off+sizeof(unwind_info),
|
||||
module->vaddr_range.min+unwind_info_off+sizeof(unwind_info)+sizeof(PE_UnwindCode)*unwind_info.codes_num),
|
||||
&is_stale, unwind_codes, endt_us);
|
||||
good_unwind_info = good_unwind_info && ctrl_process_memory_read(process->handle, r1u64(module->vaddr_range.min+unwind_info_off+sizeof(unwind_info),
|
||||
module->vaddr_range.min+unwind_info_off+sizeof(unwind_info)+sizeof(PE_UnwindCode)*unwind_info.codes_num),
|
||||
&is_stale, unwind_codes, endt_us);
|
||||
good_unwind_info = good_unwind_info && !is_stale;
|
||||
|
||||
//- rjf: bad unwind info -> abort
|
||||
@@ -2799,7 +2783,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
// rjf: read value from stack pointer
|
||||
U64 rsp = regs->rsp.u64;
|
||||
U64 value = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, rsp, &is_stale, &value, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, rsp, &is_stale, &value, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
keep_parsing = 0;
|
||||
@@ -2861,7 +2845,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
U64 off = code_ptr[1].u16*8;
|
||||
U64 addr = frame_base + off;
|
||||
U64 value = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, addr, &is_stale, &value, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, addr, &is_stale, &value, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
keep_parsing = 0;
|
||||
@@ -2880,7 +2864,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16);
|
||||
U64 addr = frame_base + off;
|
||||
U64 value = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, addr, &is_stale, &value, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, addr, &is_stale, &value, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
keep_parsing = 0;
|
||||
@@ -2911,7 +2895,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
U8 buf[16];
|
||||
U64 off = code_ptr[1].u16*16;
|
||||
U64 addr = frame_base + off;
|
||||
if(!ctrl_read_cached_process_memory(process->handle, r1u64(addr, addr+sizeof(buf)), &is_stale, buf, endt_us))
|
||||
if(!ctrl_process_memory_read(process->handle, r1u64(addr, addr+sizeof(buf)), &is_stale, buf, endt_us))
|
||||
{
|
||||
keep_parsing = 0;
|
||||
is_good = 0;
|
||||
@@ -2929,7 +2913,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
U8 buf[16];
|
||||
U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16);
|
||||
U64 addr = frame_base + off;
|
||||
if(!ctrl_read_cached_process_memory(process->handle, r1u64(addr, addr+16), &is_stale, buf, endt_us) ||
|
||||
if(!ctrl_process_memory_read(process->handle, r1u64(addr, addr+16), &is_stale, buf, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
keep_parsing = 0;
|
||||
@@ -2961,7 +2945,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
sp_adj += 8;
|
||||
}
|
||||
U64 ip_value = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, sp_adj, &is_stale, &ip_value, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, sp_adj, &is_stale, &ip_value, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
keep_parsing = 0;
|
||||
@@ -2970,7 +2954,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
}
|
||||
U64 sp_after_ip = sp_adj + 8;
|
||||
U16 ss_value = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, sp_after_ip, &is_stale, &ss_value, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, sp_after_ip, &is_stale, &ss_value, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
keep_parsing = 0;
|
||||
@@ -2979,7 +2963,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
}
|
||||
U64 sp_after_ss = sp_after_ip + 8;
|
||||
U64 rflags_value = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, sp_after_ss, &is_stale, &rflags_value, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, sp_after_ss, &is_stale, &rflags_value, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
keep_parsing = 0;
|
||||
@@ -2988,7 +2972,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
}
|
||||
U64 sp_after_rflags = sp_after_ss + 8;
|
||||
U64 sp_value = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, sp_after_rflags, &is_stale, &sp_value, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, sp_after_rflags, &is_stale, &sp_value, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
keep_parsing = 0;
|
||||
@@ -3022,7 +3006,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
U64 chained_pdata_off = unwind_info_off + sizeof(PE_UnwindInfo) + code_size;
|
||||
last_pdata = pdata;
|
||||
pdata = push_array(scratch.arena, PE_IntelPdata, 1);
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, module->vaddr_range.min+chained_pdata_off, &is_stale, pdata, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, module->vaddr_range.min+chained_pdata_off, &is_stale, pdata, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -3040,7 +3024,7 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CT
|
||||
// rjf: read rip from stack pointer
|
||||
U64 rsp = regs->rsp.u64;
|
||||
U64 new_rip = 0;
|
||||
if(!ctrl_read_cached_process_memory_struct(process->handle, rsp, &is_stale, &new_rip, endt_us) ||
|
||||
if(!ctrl_process_memory_read_struct(process->handle, rsp, &is_stale, &new_rip, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_good = 0;
|
||||
@@ -3099,7 +3083,7 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa
|
||||
U64 arch_reg_block_size = regs_block_size_from_arch(arch);
|
||||
|
||||
//- rjf: grab initial register block
|
||||
void *regs_block = ctrl_query_cached_reg_block_from_thread(scratch.arena, store, thread);
|
||||
void *regs_block = ctrl_reg_block_from_thread(scratch.arena, store, thread);
|
||||
B32 regs_block_good = (arch != Arch_Null && regs_block != 0);
|
||||
|
||||
//- rjf: loop & unwind
|
||||
@@ -4724,7 +4708,7 @@ ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U64 regs_size = regs_block_size_from_arch(entity->arch);
|
||||
void *regs = ctrl_query_cached_reg_block_from_thread(scratch.arena, ctrl_state->ctrl_thread_entity_store, entity->handle);
|
||||
void *regs = ctrl_reg_block_from_thread(scratch.arena, ctrl_state->ctrl_thread_entity_store, entity->handle);
|
||||
Rng1U64 legal_range = r1u64(0, regs_size);
|
||||
Rng1U64 read_range = intersect_1u64(legal_range, range);
|
||||
U64 read_size = dim_1u64(read_range);
|
||||
|
||||
+46
-8
@@ -593,6 +593,44 @@ struct CTRL_ThreadRegCache
|
||||
CTRL_ThreadRegCacheStripe *stripes;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Unwind Cache Types
|
||||
|
||||
typedef struct CTRL_ThreadUnwindCacheNode CTRL_ThreadUnwindCacheNode;
|
||||
struct CTRL_ThreadUnwindCacheNode
|
||||
{
|
||||
CTRL_ThreadUnwindCacheNode *next;
|
||||
CTRL_ThreadUnwindCacheNode *prev;
|
||||
Arena *arena;
|
||||
CTRL_Handle thread;
|
||||
U64 reg_gen;
|
||||
U64 mem_gen;
|
||||
CTRL_Unwind unwind;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ThreadUnwindCacheSlot CTRL_ThreadUnwindCacheSlot;
|
||||
struct CTRL_ThreadUnwindCacheSlot
|
||||
{
|
||||
CTRL_ThreadUnwindCacheNode *first;
|
||||
CTRL_ThreadUnwindCacheNode *last;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ThreadUnwindCacheStripe CTRL_ThreadUnwindCacheStripe;
|
||||
struct CTRL_ThreadUnwindCacheStripe
|
||||
{
|
||||
Arena *arena;
|
||||
OS_Handle rw_mutex;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ThreadUnwindCache CTRL_ThreadUnwindCache;
|
||||
struct CTRL_ThreadUnwindCache
|
||||
{
|
||||
U64 slots_count;
|
||||
CTRL_ThreadUnwindCacheSlot *slots;
|
||||
U64 stripes_count;
|
||||
CTRL_ThreadUnwindCacheStripe *stripes;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Module Image Info Cache Types
|
||||
|
||||
@@ -686,6 +724,7 @@ struct CTRL_State
|
||||
// rjf: caches
|
||||
CTRL_ProcessMemoryCache process_memory_cache;
|
||||
CTRL_ThreadRegCache thread_reg_cache;
|
||||
CTRL_ThreadUnwindCache thread_unwind_cache;
|
||||
CTRL_ModuleImageInfoCache module_image_info_cache;
|
||||
|
||||
// rjf: user -> ctrl msg ring buffer
|
||||
@@ -885,10 +924,9 @@ internal U128 ctrl_stored_hash_from_process_vaddr_range(CTRL_Handle process, Rng
|
||||
internal U128 ctrl_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated);
|
||||
|
||||
//- rjf: process memory cache reading helpers
|
||||
internal CTRL_ProcessMemorySlice ctrl_query_cached_data_from_process_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us);
|
||||
internal CTRL_ProcessMemorySlice ctrl_query_cached_zero_terminated_data_from_process_vaddr_limit(Arena *arena, CTRL_Handle process, U64 vaddr, U64 limit, U64 element_size, U64 endt_us);
|
||||
internal B32 ctrl_read_cached_process_memory(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us);
|
||||
#define ctrl_read_cached_process_memory_struct(process, vaddr, is_stale_out, ptr, endt_us) ctrl_read_cached_process_memory((process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us))
|
||||
internal CTRL_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, 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))
|
||||
|
||||
//- rjf: process memory writing
|
||||
internal B32 ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src);
|
||||
@@ -897,10 +935,10 @@ internal B32 ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src);
|
||||
//~ rjf: Thread Register Functions
|
||||
|
||||
//- rjf: thread register cache reading
|
||||
internal void *ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle);
|
||||
internal U64 ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle);
|
||||
internal U64 ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle);
|
||||
internal U64 ctrl_query_cached_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle);
|
||||
internal void *ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle);
|
||||
internal U64 ctrl_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle);
|
||||
internal U64 ctrl_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle);
|
||||
internal U64 ctrl_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle);
|
||||
|
||||
//- rjf: thread register writing
|
||||
internal B32 ctrl_thread_write_reg_block(CTRL_Handle thread, void *block);
|
||||
|
||||
@@ -300,13 +300,13 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread)
|
||||
// rjf: thread => unpacked info
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
|
||||
Arch arch = thread->arch;
|
||||
U64 ip_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
U64 ip_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
|
||||
// rjf: ip => machine code
|
||||
String8 machine_code = {0};
|
||||
{
|
||||
Rng1U64 rng = r1u64(ip_vaddr, ip_vaddr+max_instruction_size_from_arch(arch));
|
||||
CTRL_ProcessMemorySlice machine_code_slice = ctrl_query_cached_data_from_process_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, os_now_microseconds()+5000);
|
||||
machine_code = machine_code_slice.data;
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
|
||||
|
||||
// rjf: thread => info
|
||||
Arch arch = thread->arch;
|
||||
U64 ip_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
U64 ip_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr);
|
||||
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
|
||||
@@ -380,7 +380,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
|
||||
String8 machine_code = {0};
|
||||
if(good_line_info)
|
||||
{
|
||||
CTRL_ProcessMemorySlice machine_code_slice = ctrl_query_cached_data_from_process_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, os_now_microseconds()+50000);
|
||||
machine_code = machine_code_slice.data;
|
||||
LogInfoNamedBlockF("machine_code_slice")
|
||||
{
|
||||
@@ -498,7 +498,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
|
||||
|
||||
// rjf: thread => info
|
||||
Arch arch = thread->arch;
|
||||
U64 ip_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
U64 ip_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr);
|
||||
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
|
||||
@@ -536,7 +536,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
|
||||
String8 machine_code = {0};
|
||||
if(good_line_info)
|
||||
{
|
||||
CTRL_ProcessMemorySlice machine_code_slice = ctrl_query_cached_data_from_process_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, os_now_microseconds()+5000);
|
||||
machine_code = machine_code_slice.data;
|
||||
}
|
||||
|
||||
@@ -1073,7 +1073,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_query_cached_data_from_process_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);
|
||||
if(tls_index_slice.data.size >= addr_size)
|
||||
{
|
||||
tls_index = *(U64 *)tls_index_slice.data.str;
|
||||
@@ -1086,13 +1086,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_query_cached_data_from_process_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);
|
||||
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_query_cached_data_from_process_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);
|
||||
String8 result_data = result_slice.data;
|
||||
if(result_data.size >= 8)
|
||||
{
|
||||
@@ -1267,7 +1267,7 @@ d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count)
|
||||
U64 result = 0;
|
||||
if(unwind_count == 0)
|
||||
{
|
||||
result = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
result = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2020,7 +2020,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
||||
{
|
||||
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->thread);
|
||||
U64 vaddr = params->vaddr;
|
||||
void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle);
|
||||
void *block = ctrl_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle);
|
||||
regs_arch_block_write_rip(thread->arch, block, vaddr);
|
||||
B32 result = ctrl_thread_write_reg_block(thread->handle, block);
|
||||
|
||||
|
||||
@@ -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_query_cached_data_from_process_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, rd_state->frame_eval_memread_endt_us);
|
||||
String8 data = slice.data;
|
||||
if(data.size == dim_1u64(range))
|
||||
{
|
||||
@@ -2021,7 +2021,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range)
|
||||
Rng1U64 legal_range = r1u64(0, regs_size);
|
||||
Rng1U64 write_range = intersect_1u64(legal_range, range);
|
||||
U64 write_size = dim_1u64(write_range);
|
||||
void *new_regs = ctrl_query_cached_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, entity->handle);
|
||||
void *new_regs = ctrl_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, entity->handle);
|
||||
MemoryCopy((U8 *)new_regs + write_range.min, in, write_size);
|
||||
result = ctrl_thread_write_reg_block(entity->handle, new_regs);
|
||||
scratch_end(scratch);
|
||||
@@ -4508,7 +4508,7 @@ rd_view_ui(Rng2F32 rect)
|
||||
U64 size = e_type_byte_size_from_key(row->eval.irtree.type_key);
|
||||
size = Min(size, 64);
|
||||
Rng1U64 vaddr_rng = r1u64(row->eval.value.u64, row->eval.value.u64+size);
|
||||
CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, rd_state->frame_eval_memread_endt_us);
|
||||
CTRL_ProcessMemorySlice slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, space_entity->handle, vaddr_rng, 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)
|
||||
@@ -11644,7 +11644,7 @@ rd_frame(void)
|
||||
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
|
||||
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
|
||||
U64 tls_root_vaddr = ctrl_query_cached_tls_root_vaddr_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
U64 tls_root_vaddr = ctrl_tls_root_vaddr_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module);
|
||||
U64 eval_modules_count = Max(1, all_modules.count);
|
||||
E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count);
|
||||
@@ -15650,7 +15650,7 @@ rd_frame(void)
|
||||
{
|
||||
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread);
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle));
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle));
|
||||
CTRL_Entity *machine = ctrl_entity_ancestor_from_kind(process, CTRL_EntityKind_Machine);
|
||||
rd_state->base_regs.v.unwind_count = 0;
|
||||
rd_state->base_regs.v.inline_depth = 0;
|
||||
@@ -16423,7 +16423,7 @@ rd_frame(void)
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr);
|
||||
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
|
||||
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
|
||||
U64 test_cached_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
U64 test_cached_vaddr = ctrl_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
|
||||
|
||||
// rjf: valid stop thread? -> select & snap
|
||||
if(need_refocus && thread != &ctrl_entity_nil && evt->cause != D_EventCause_Halt)
|
||||
|
||||
Reference in New Issue
Block a user