mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-10-14 12:59:41 -07:00
use synchronous reads for call stack computation, but extend artifact cache with the ability to say that a non-retryable failure occurred, so that we can fall back to stale call stacks
This commit is contained in:
1 parent
3d6851c57a
commit
1901e67f39
19 files changed
+122
-96
No files matched your search
@@ -1781,9 +1781,10 @@ d_unwind_from_thread(Arena *arena, D_Handle thread, U64 endt_us)
|
||||
D_Unwind unwind = { .flags = D_UnwindFlag_Error };
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: grab run state pre-unwind computing
|
||||
//- rjf: grab generations pre-unwind computing
|
||||
//
|
||||
U64 run_gen = d_run_gen();
|
||||
U64 mem_gen = d_mem_gen();
|
||||
U64 reg_gen = d_reg_gen();
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: unpack args
|
||||
@@ -1889,19 +1890,16 @@ d_unwind_from_thread(Arena *arena, D_Handle thread, U64 endt_us)
|
||||
// stale. if it can't be read, the unwind fails.
|
||||
if(step.status == UWND_StepStatus_FailedMemoryRead)
|
||||
{
|
||||
D_ProcessMemorySlice slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process_entity->handle, step.missed_read_vaddr_range, 1, endt_us);
|
||||
String8 data = slice.data;
|
||||
if(slice.stale)
|
||||
U64 size_desired = dim_1u64(step.missed_read_vaddr_range);
|
||||
U8 *data = push_array(scratch.arena, U8, size_desired);
|
||||
U64 size = d_process_read(process_entity->handle, step.missed_read_vaddr_range, data);
|
||||
if(size == size_desired)
|
||||
{
|
||||
unwind.flags |= D_UnwindFlag_Stale;
|
||||
}
|
||||
else if(data.size < dim_1u64(step.missed_read_vaddr_range))
|
||||
{
|
||||
unwind.flags |= D_UnwindFlag_Error;
|
||||
memory_map_push(scratch.arena, &memory_map, step.missed_read_vaddr_range, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_map_push(scratch.arena, &memory_map, step.missed_read_vaddr_range, data.str);
|
||||
unwind.flags |= D_UnwindFlag_Error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1949,6 +1947,18 @@ d_unwind_from_thread(Arena *arena, D_Handle thread, U64 endt_us)
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: if we failed, but our generations changed, mark the 'stale' bit
|
||||
if(unwind.flags & D_UnwindFlag_Error)
|
||||
{
|
||||
U64 post_reg_gen = d_reg_gen();
|
||||
U64 post_mem_gen = d_mem_gen();
|
||||
if(post_reg_gen != reg_gen ||
|
||||
post_mem_gen != mem_gen)
|
||||
{
|
||||
unwind.flags |= D_UnwindFlag_Stale;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: bake frames list into result array
|
||||
{
|
||||
unwind.frames.count = frame_node_count;
|
||||
@@ -5626,7 +5636,7 @@ d_data_from_process_vaddr_range(Arena *arena, D_Handle process, Rng1U64 vaddr_ra
|
||||
//- rjf: process memory artifact cache
|
||||
|
||||
internal AC_Artifact
|
||||
d_memory_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out)
|
||||
d_memory_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64 *gen_out)
|
||||
{
|
||||
AC_Artifact artifact = {0};
|
||||
{
|
||||
@@ -5768,7 +5778,7 @@ d_memory_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *g
|
||||
//- rjf: retry on mem gen "tearing", and if the range is non-empty
|
||||
if(pre_read_mem_gen != post_read_mem_gen && range_size != 0)
|
||||
{
|
||||
retry_out[0] = 1;
|
||||
status_out[0] = AC_Status_NeedRetry;
|
||||
}
|
||||
|
||||
//- rjf: bundle content key as artifact
|
||||
@@ -5981,7 +5991,7 @@ d_process_memory_read(D_Handle process, Rng1U64 range, B32 *is_stale_out, void *
|
||||
//~ rjf: TLS Address Artifact Cache Hooks / Lookups
|
||||
|
||||
internal AC_Artifact
|
||||
d_tls_vaddr_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out)
|
||||
d_tls_vaddr_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64 *gen_out)
|
||||
{
|
||||
// rjf: unpack key
|
||||
D_Handle thread = {0};
|
||||
@@ -6008,7 +6018,7 @@ d_tls_vaddr_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64
|
||||
// rjf: if not successful -> retry
|
||||
if(!success)
|
||||
{
|
||||
retry_out[0] = 1;
|
||||
status_out[0] = AC_Status_NeedRetry;
|
||||
}
|
||||
|
||||
// rjf: package as artifact
|
||||
@@ -6017,11 +6027,6 @@ d_tls_vaddr_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64
|
||||
return artifact;
|
||||
}
|
||||
|
||||
internal void d_tls_vaddr_artifact_destroy(AC_Artifact artifact)
|
||||
{
|
||||
// NOTE(rjf): no-op
|
||||
}
|
||||
|
||||
internal U64
|
||||
d_cached_tls_vaddr_from_thread_module(D_Handle thread_handle, D_Handle module_handle, U64 endt_us, B32 *stale_out)
|
||||
{
|
||||
@@ -6029,7 +6034,7 @@ d_cached_tls_vaddr_from_thread_module(D_Handle thread_handle, D_Handle module_ha
|
||||
Access *access = access_open();
|
||||
D_Handle key_data[] = {thread_handle, module_handle};
|
||||
String8 key = str8((U8 *)&key_data[0], sizeof(key_data));
|
||||
AC_Artifact artifact = ac_artifact_from_key(access, key, d_tls_vaddr_artifact_create, d_tls_vaddr_artifact_destroy, endt_us, .stale_out = stale_out);
|
||||
AC_Artifact artifact = ac_artifact_from_key(access, key, d_tls_vaddr_artifact_create, 0, endt_us, .stale_out = stale_out);
|
||||
result = artifact.u64[0];
|
||||
access_close(access);
|
||||
return result;
|
||||
@@ -6039,7 +6044,7 @@ d_cached_tls_vaddr_from_thread_module(D_Handle thread_handle, D_Handle module_ha
|
||||
//~ rjf: Call Stack Artifact Cache Hooks / Lookups
|
||||
|
||||
internal AC_Artifact
|
||||
d_call_stack_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out)
|
||||
d_call_stack_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64 *gen_out)
|
||||
{
|
||||
AC_Artifact artifact = {0};
|
||||
{
|
||||
@@ -6168,14 +6173,19 @@ d_call_stack_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U6
|
||||
pre_reg_gen = d_reg_gen();
|
||||
pre_mem_gen = d_mem_gen();
|
||||
unwind = d_unwind_from_thread(arena, thread_handle, now_time_us()+100);
|
||||
if(!(unwind.flags & D_UnwindFlag_Stale))
|
||||
if(unwind.flags & D_UnwindFlag_Stale)
|
||||
{
|
||||
good = 1;
|
||||
call_stack[0] = d_call_stack_from_unwind(arena, process, &unwind);
|
||||
retry = 1;
|
||||
}
|
||||
else if(unwind.flags & D_UnwindFlag_Error)
|
||||
{
|
||||
good = 0;
|
||||
retry = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
retry = 1;
|
||||
good = 1;
|
||||
call_stack[0] = d_call_stack_from_unwind(arena, process, &unwind);
|
||||
}
|
||||
post_reg_gen = d_reg_gen();
|
||||
post_mem_gen = d_mem_gen();
|
||||
@@ -6204,8 +6214,19 @@ d_call_stack_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U6
|
||||
artifact.u64[1] = (U64)call_stack;
|
||||
}
|
||||
|
||||
//- rjf: mark retry
|
||||
retry_out[0] = retry;
|
||||
//- rjf: mark status
|
||||
if(retry)
|
||||
{
|
||||
status_out[0] = AC_Status_NeedRetry;
|
||||
}
|
||||
else if(good)
|
||||
{
|
||||
status_out[0] = AC_Status_Good;
|
||||
}
|
||||
else
|
||||
{
|
||||
status_out[0] = AC_Status_Failed;
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
@@ -6243,7 +6264,7 @@ d_call_stack_from_thread(Access *access, D_Handle thread_handle, B32 high_priori
|
||||
//~ rjf: Call Stack Tree Artifact Cache Hooks / Lookups
|
||||
|
||||
internal AC_Artifact
|
||||
d_call_stack_tree_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out)
|
||||
d_call_stack_tree_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64 *gen_out)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
Access *access = access_open();
|
||||
@@ -6354,7 +6375,7 @@ d_call_stack_tree_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_ou
|
||||
//- rjf: retry on stale
|
||||
if(stale)
|
||||
{
|
||||
retry_out[0] = 1;
|
||||
status_out[0] = AC_Status_NeedRetry;
|
||||
}
|
||||
|
||||
access_close(access);
|
||||
|
||||
@@ -640,7 +640,7 @@ internal String8 d_data_from_process_vaddr_range(Arena *arena, D_Handle process,
|
||||
#define d_process_write_struct(process, vaddr, ptr) d_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), (ptr))
|
||||
|
||||
//- rjf: process memory artifact cache
|
||||
internal AC_Artifact d_memory_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
|
||||
internal AC_Artifact d_memory_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64 *gen_out);
|
||||
internal void d_memory_artifact_destroy(AC_Artifact artifact);
|
||||
internal C_Key d_key_from_process_vaddr_range(D_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, B32 wait_for_fresh, U64 endt_us, B32 *out_is_stale);
|
||||
|
||||
@@ -652,21 +652,20 @@ internal B32 d_process_memory_read(D_Handle process, Rng1U64 range, B32 *is_stal
|
||||
////////////////////////////////
|
||||
//~ rjf: TLS Address Artifact Cache Hooks / Lookups
|
||||
|
||||
internal AC_Artifact d_tls_vaddr_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
|
||||
internal void d_tls_vaddr_artifact_destroy(AC_Artifact artifact);
|
||||
internal AC_Artifact d_tls_vaddr_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64 *gen_out);
|
||||
internal U64 d_cached_tls_vaddr_from_thread_module(D_Handle thread_handle, D_Handle module_handle, U64 endt_us, B32 *stale_out);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Call Stack Artifact Cache Hooks / Lookups
|
||||
|
||||
internal AC_Artifact d_call_stack_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
|
||||
internal AC_Artifact d_call_stack_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64 *gen_out);
|
||||
internal void d_call_stack_artifact_destroy(AC_Artifact artifact);
|
||||
internal D_CallStack d_call_stack_from_thread(Access *access, D_Handle thread_handle, B32 high_priority, U64 endt_us);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Call Stack Tree Artifact Cache Hooks / Lookups
|
||||
|
||||
internal AC_Artifact d_call_stack_tree_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
|
||||
internal AC_Artifact d_call_stack_tree_artifact_create(String8 key, B32 *cancel_signal, AC_Status *status_out, U64 *gen_out);
|
||||
internal void d_call_stack_tree_artifact_destroy(AC_Artifact artifact);
|
||||
internal D_CallStackTree d_call_stack_tree(Access *access, U64 endt_us);
|
||||
|
||||
|
||||
Reference in new issue
Block a user