mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-26 21:44:59 -07:00
first pass at call stack cache, need a lot of clean up before this is working...
This commit is contained in:
+72
-26
@@ -1443,7 +1443,7 @@ ctrl_scope_close(CTRL_Scope *scope)
|
||||
internal void
|
||||
ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheNode *node)
|
||||
{
|
||||
ins_atomic_u64_eval(&node->scope_touch_count);
|
||||
ins_atomic_u64_inc_eval(&node->scope_touch_count);
|
||||
CTRL_ScopeCallStackTouch *touch = ctrl_tctx->free_call_stack_touch;
|
||||
if(touch != 0)
|
||||
{
|
||||
@@ -3299,13 +3299,21 @@ ctrl_call_stack_from_unwind(Arena *arena, CTRL_Entity *process, CTRL_Unwind *bas
|
||||
}
|
||||
|
||||
//- rjf: package
|
||||
result.count = frame_count;
|
||||
result.frames = push_array(arena, CTRL_CallStackFrame, result.count);
|
||||
result.frames_count = frame_count;
|
||||
result.frames = push_array(arena, CTRL_CallStackFrame, result.frames_count);
|
||||
result.concrete_frames_count = base_unwind->frames.count;
|
||||
result.concrete_frames = push_array(arena, CTRL_CallStackFrame *, result.concrete_frames_count);
|
||||
{
|
||||
U64 idx = 0;
|
||||
U64 concrete_idx = 0;
|
||||
for(FrameNode *n = first_frame; n != 0; n = n->next, idx += 1)
|
||||
{
|
||||
MemoryCopyStruct(&result.frames[idx], &n->v);
|
||||
if(n->v.inline_depth == 0 && concrete_idx < result.concrete_frames_count)
|
||||
{
|
||||
result.concrete_frames[concrete_idx] = &result.frames[idx];
|
||||
concrete_idx += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3320,7 +3328,7 @@ ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U
|
||||
CTRL_CallStackFrame *f = 0;
|
||||
{
|
||||
U64 base_frame_idx = 0;
|
||||
for(U64 idx = 0; idx < call_stack->count; idx += 1)
|
||||
for(U64 idx = 0; idx < call_stack->frames_count; idx += 1)
|
||||
{
|
||||
if(call_stack->frames[idx].inline_depth == 0)
|
||||
{
|
||||
@@ -3361,7 +3369,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us)
|
||||
//- rjf: loop: try to grab cached call stack; request; wait
|
||||
U64 reg_gen = ctrl_reg_gen();
|
||||
U64 mem_gen = ctrl_mem_gen();
|
||||
OS_MutexScopeW(stripe->rw_mutex) for(;;)
|
||||
OS_MutexScopeR(stripe->rw_mutex) for(;;)
|
||||
{
|
||||
//- rjf: try to grab cached
|
||||
B32 is_good = 0;
|
||||
@@ -3385,20 +3393,31 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us)
|
||||
}
|
||||
|
||||
//- rjf: create node if needed
|
||||
if(!is_good)
|
||||
if(!is_good) OS_MutexScopeRWPromote(stripe->rw_mutex)
|
||||
{
|
||||
node = push_array(stripe->arena, CTRL_CallStackCacheNode, 1);
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
node->thread = thread->handle;
|
||||
for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(ctrl_handle_match(n->thread, handle))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(node == 0)
|
||||
{
|
||||
node = push_array(stripe->arena, CTRL_CallStackCacheNode, 1);
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
node->thread = thread->handle;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: request if needed
|
||||
if(!is_working && (!is_good || !is_stale))
|
||||
if(!is_working && (!is_good || is_stale))
|
||||
{
|
||||
if(ctrl_u2csb_enqueue_req(thread->handle, endt_us) &&
|
||||
async_push_work(ctrl_call_stack_build_work))
|
||||
{
|
||||
node->working_count += 1;
|
||||
ins_atomic_u64_inc_eval(&node->working_count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3409,7 +3428,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us)
|
||||
}
|
||||
|
||||
//- rjf: time to wait for new result? -> wait
|
||||
os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, endt_us);
|
||||
os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us);
|
||||
}
|
||||
}
|
||||
return call_stack;
|
||||
@@ -6784,30 +6803,47 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work)
|
||||
U64 pre_reg_gen = ctrl_reg_gen();
|
||||
U64 pre_mem_gen = ctrl_mem_gen();
|
||||
Arena *arena = arena_alloc();
|
||||
CTRL_Unwind unwind = ctrl_unwind_from_thread(arena, ctx, thread_handle, os_now_microseconds()+1000000);
|
||||
CTRL_Unwind unwind = ctrl_unwind_from_thread(arena, ctx, thread_handle, 0);
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(arena, process, &unwind);
|
||||
U64 post_reg_gen = ctrl_reg_gen();
|
||||
U64 post_mem_gen = ctrl_mem_gen();
|
||||
|
||||
//- rjf: store in cache
|
||||
//- rjf: store new results in cache
|
||||
Arena *last_arena = arena;
|
||||
OS_MutexScopeW(stripe->rw_mutex)
|
||||
if(pre_reg_gen == post_reg_gen &&
|
||||
pre_mem_gen == post_mem_gen)
|
||||
{
|
||||
for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
for(B32 done = 0; !done;)
|
||||
{
|
||||
if(ctrl_handle_match(n->thread, thread_handle))
|
||||
B32 found = 0;
|
||||
OS_MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
if(pre_reg_gen == post_reg_gen &&
|
||||
pre_mem_gen == post_mem_gen)
|
||||
for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
last_arena = n->arena;
|
||||
n->arena = arena;
|
||||
n->reg_gen = pre_reg_gen;
|
||||
n->mem_gen = pre_mem_gen;
|
||||
n->unwind = unwind;
|
||||
n->call_stack = call_stack;
|
||||
if(ctrl_handle_match(n->thread, thread_handle))
|
||||
{
|
||||
found = 1;
|
||||
if(n->scope_touch_count == 0)
|
||||
{
|
||||
done = 1;
|
||||
if(unwind.flags == 0 || call_stack.frames_count >= n->call_stack.frames_count)
|
||||
{
|
||||
last_arena = n->arena;
|
||||
n->arena = arena;
|
||||
n->call_stack = call_stack;
|
||||
}
|
||||
if(unwind.flags == 0)
|
||||
{
|
||||
n->reg_gen = pre_reg_gen;
|
||||
n->mem_gen = pre_mem_gen;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
n->working_count -= 1;
|
||||
}
|
||||
if(!found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -6819,6 +6855,16 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work)
|
||||
arena_release(last_arena);
|
||||
}
|
||||
|
||||
//- rjf: mark work as done
|
||||
OS_MutexScopeW(stripe->rw_mutex) for(CTRL_CallStackCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(ctrl_handle_match(n->thread, thread_handle))
|
||||
{
|
||||
ins_atomic_u64_dec_eval(&n->working_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
|
||||
+12
-5
@@ -266,7 +266,9 @@ typedef struct CTRL_CallStack CTRL_CallStack;
|
||||
struct CTRL_CallStack
|
||||
{
|
||||
CTRL_CallStackFrame *frames;
|
||||
U64 count;
|
||||
U64 frames_count;
|
||||
CTRL_CallStackFrame **concrete_frames;
|
||||
U64 concrete_frames_count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -609,13 +611,18 @@ struct CTRL_CallStackCacheNode
|
||||
{
|
||||
CTRL_CallStackCacheNode *next;
|
||||
CTRL_CallStackCacheNode *prev;
|
||||
|
||||
// rjf: key
|
||||
CTRL_Handle thread;
|
||||
U64 scope_touch_count;
|
||||
U64 working_count;
|
||||
Arena *arena;
|
||||
U64 reg_gen;
|
||||
U64 mem_gen;
|
||||
CTRL_Unwind unwind;
|
||||
|
||||
// rjf: refcounts
|
||||
U64 scope_touch_count;
|
||||
U64 working_count;
|
||||
|
||||
// rjf: value
|
||||
Arena *arena;
|
||||
CTRL_CallStack call_stack;
|
||||
};
|
||||
|
||||
|
||||
+24
-18
@@ -1815,11 +1815,12 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
|
||||
}break;
|
||||
case CTRL_EntityKind_Thread:
|
||||
{
|
||||
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity);
|
||||
U64 frame_idx = e_interpret_ctx->reg_unwind_count;
|
||||
if(frame_idx < unwind.frames.count)
|
||||
CTRL_Scope *ctrl_scope = ctrl_scope_open();
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0);
|
||||
U64 concrete_frame_idx = e_interpret_ctx->reg_unwind_count;
|
||||
if(concrete_frame_idx < call_stack.concrete_frames_count)
|
||||
{
|
||||
CTRL_UnwindFrame *f = &unwind.frames.v[frame_idx];
|
||||
CTRL_CallStackFrame *f = call_stack.concrete_frames[concrete_frame_idx];
|
||||
U64 regs_size = regs_block_size_from_arch(e_interpret_ctx->reg_arch);
|
||||
Rng1U64 legal_range = r1u64(0, regs_size);
|
||||
Rng1U64 read_range = intersect_1u64(legal_range, range);
|
||||
@@ -1827,6 +1828,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
|
||||
MemoryCopy(out, (U8 *)f->regs + read_range.min, read_size);
|
||||
result = (read_size == dim_1u64(range));
|
||||
}
|
||||
ctrl_scope_close(ctrl_scope);
|
||||
}break;
|
||||
}
|
||||
}break;
|
||||
@@ -6393,12 +6395,12 @@ rd_window_frame(void)
|
||||
// rjf: unwind
|
||||
if(ctrl_entity->kind == CTRL_EntityKind_Thread) RD_Font(RD_FontSlot_Code)
|
||||
{
|
||||
CTRL_Scope *ctrl_scope = ctrl_scope_open();
|
||||
Vec4F32 code_color = ui_color_from_name(str8_lit("code_default"));
|
||||
Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol"));
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process);
|
||||
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(ctrl_entity);
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &base_unwind);
|
||||
if(call_stack.count != 0)
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, ctrl_entity, 0);
|
||||
if(call_stack.frames_count != 0)
|
||||
{
|
||||
ui_spacer(ui_em(1.5f, 1.f));
|
||||
}
|
||||
@@ -6414,6 +6416,7 @@ rd_window_frame(void)
|
||||
String8 rip_value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), &string_params, ui_top_font(), ui_top_font_size(), ui_top_font_size()*40.f, rip_eval);
|
||||
rd_code_label(1, 0, code_color, rip_value_string);
|
||||
}
|
||||
ctrl_scope_close(ctrl_scope);
|
||||
}
|
||||
|
||||
}break;
|
||||
@@ -11238,10 +11241,12 @@ rd_frame(void)
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: open frame debug info scope
|
||||
//- rjf: open frame scopes
|
||||
//
|
||||
if(rd_state->frame_depth == 0)
|
||||
{
|
||||
rd_state->frame_di_scope = di_scope_open();
|
||||
rd_state->frame_ctrl_scope = ctrl_scope_open();
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@@ -11283,7 +11288,7 @@ rd_frame(void)
|
||||
U64 candidate_frame_time_us = 1000000/(U64)candidate;
|
||||
S64 frame_time_us_diff = (S64)frame_time_history_avg_us - (S64)candidate_frame_time_us;
|
||||
if(abs_s64(frame_time_us_diff) < best_target_hz_frame_time_us_diff &&
|
||||
frame_time_history_avg_us < candidate_frame_time_us + 1000)
|
||||
frame_time_history_avg_us < candidate_frame_time_us + candidate_frame_time_us/4)
|
||||
{
|
||||
best_target_hz = candidate;
|
||||
best_target_hz_frame_time_us_diff = frame_time_us_diff;
|
||||
@@ -11613,7 +11618,6 @@ rd_frame(void)
|
||||
Arch arch = thread->arch;
|
||||
U64 unwind_count = rd_regs()->unwind_count;
|
||||
U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count);
|
||||
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_tls_root_vaddr_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle);
|
||||
@@ -15634,10 +15638,9 @@ rd_frame(void)
|
||||
}break;
|
||||
case RD_CmdKind_SelectUnwind:
|
||||
{
|
||||
CTRL_Scope *ctrl_scope = ctrl_scope_open();
|
||||
CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread);
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
|
||||
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread);
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &base_unwind);
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, os_now_microseconds()+10000);
|
||||
CTRL_CallStackFrame *frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth);
|
||||
if(frame == 0)
|
||||
{
|
||||
@@ -15649,14 +15652,14 @@ rd_frame(void)
|
||||
rd_state->base_regs.v.inline_depth = rd_regs()->inline_depth;
|
||||
}
|
||||
rd_cmd(RD_CmdKind_FindThread, .thread = thread->handle, .unwind_count = rd_state->base_regs.v.unwind_count, .inline_depth = rd_state->base_regs.v.inline_depth);
|
||||
ctrl_scope_close(ctrl_scope);
|
||||
}break;
|
||||
case RD_CmdKind_UpOneFrame:
|
||||
case RD_CmdKind_DownOneFrame:
|
||||
{
|
||||
CTRL_Scope *ctrl_scope = ctrl_scope_open();
|
||||
CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread);
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
|
||||
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread);
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, process, &base_unwind);
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, os_now_microseconds()+10000);
|
||||
CTRL_CallStackFrame *current_frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth);
|
||||
CTRL_CallStackFrame *next_frame = current_frame;
|
||||
if(current_frame != 0) switch(kind)
|
||||
@@ -15668,7 +15671,7 @@ rd_frame(void)
|
||||
next_frame = current_frame-1;
|
||||
}break;
|
||||
case RD_CmdKind_DownOneFrame:
|
||||
if(current_frame+1 < call_stack.frames + call_stack.count)
|
||||
if(current_frame+1 < call_stack.frames + call_stack.frames_count)
|
||||
{
|
||||
next_frame = current_frame+1;
|
||||
}break;
|
||||
@@ -15680,6 +15683,7 @@ rd_frame(void)
|
||||
.unwind_count = next_frame->unwind_count,
|
||||
.inline_depth = next_frame->inline_depth);
|
||||
}
|
||||
ctrl_scope_close(ctrl_scope);
|
||||
}break;
|
||||
|
||||
//- rjf: meta controls
|
||||
@@ -16700,10 +16704,12 @@ rd_frame(void)
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: close frame debug info scope
|
||||
//- rjf: close frame scopes
|
||||
//
|
||||
if(rd_state->frame_depth == 0)
|
||||
{
|
||||
di_scope_close(rd_state->frame_di_scope);
|
||||
ctrl_scope_close(rd_state->frame_ctrl_scope);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
@@ -599,6 +599,7 @@ struct RD_State
|
||||
// rjf: frame parameters
|
||||
F32 frame_dt;
|
||||
DI_Scope *frame_di_scope;
|
||||
CTRL_Scope *frame_ctrl_scope;
|
||||
|
||||
// rjf: dbgi match store
|
||||
DI_MatchStore *match_store;
|
||||
|
||||
@@ -955,11 +955,9 @@ E_TYPE_IREXT_FUNCTION_DEF(call_stack)
|
||||
CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(interp.space);
|
||||
if(entity->kind == CTRL_EntityKind_Thread)
|
||||
{
|
||||
CTRL_Entity *process = ctrl_process_from_entity(entity);
|
||||
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity);
|
||||
accel->arch = entity->arch;
|
||||
accel->process = process->handle;
|
||||
accel->call_stack = ctrl_call_stack_from_unwind(arena, process, &base_unwind);
|
||||
accel->process = ctrl_process_from_entity(entity)->handle;
|
||||
accel->call_stack = ctrl_call_stack_from_thread(rd_state->frame_ctrl_scope, entity, 0);
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
@@ -975,7 +973,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(call_stack)
|
||||
RD_CallStackAccel *accel = (RD_CallStackAccel *)lhs_irtree->user_data;
|
||||
E_Value rhs_value = e_value_from_expr(expr->first->next);
|
||||
CTRL_CallStack *call_stack = &accel->call_stack;
|
||||
if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count)
|
||||
if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->frames_count)
|
||||
{
|
||||
CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, accel->process);
|
||||
CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64];
|
||||
@@ -992,7 +990,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack)
|
||||
RD_CallStackAccel *accel = (RD_CallStackAccel *)eval.irtree.user_data;
|
||||
E_TypeExpandInfo result = {0};
|
||||
result.user_data = accel;
|
||||
result.expr_count = accel->call_stack.count;
|
||||
result.expr_count = accel->call_stack.frames_count;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+13
-10
@@ -1008,17 +1008,18 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row)
|
||||
CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(block_eval.space);
|
||||
if(entity->kind == CTRL_EntityKind_Thread)
|
||||
{
|
||||
CTRL_Scope *ctrl_scope = ctrl_scope_open();
|
||||
info.callstack_thread = entity;
|
||||
U64 frame_num = ev_block_num_from_id(block, key.child_id);
|
||||
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity);
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, ctrl_process_from_entity(entity), &unwind);
|
||||
if(1 <= frame_num && frame_num <= call_stack.count)
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0);
|
||||
if(1 <= frame_num && frame_num <= call_stack.frames_count)
|
||||
{
|
||||
CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1];
|
||||
info.callstack_unwind_index = f->unwind_count;
|
||||
info.callstack_inline_depth = f->inline_depth;
|
||||
info.callstack_vaddr = regs_rip_from_arch_block(entity->arch, f->regs);
|
||||
}
|
||||
ctrl_scope_close(ctrl_scope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2837,17 +2838,18 @@ RD_VIEW_UI_FUNCTION_DEF(memory)
|
||||
};
|
||||
AnnotationList *visible_memory_annotations = push_array(scratch.arena, AnnotationList, visible_memory_size);
|
||||
{
|
||||
CTRL_Scope *ctrl_scope = ctrl_scope_open();
|
||||
CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread);
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
|
||||
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread);
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 0);
|
||||
|
||||
//- rjf: fill unwind frame annotations
|
||||
if(unwind.frames.count != 0) UI_Tag(str8_lit("weak"))
|
||||
if(call_stack.concrete_frames_count != 0) UI_Tag(str8_lit("weak"))
|
||||
{
|
||||
U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, unwind.frames.v[0].regs);
|
||||
for(U64 idx = 1; idx < unwind.frames.count; idx += 1)
|
||||
U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, call_stack.concrete_frames[0]->regs);
|
||||
for(U64 idx = 1; idx < call_stack.concrete_frames_count; idx += 1)
|
||||
{
|
||||
CTRL_UnwindFrame *f = &unwind.frames.v[idx];
|
||||
CTRL_CallStackFrame *f = call_stack.concrete_frames[idx];
|
||||
U64 f_stack_top = regs_rsp_from_arch_block(thread->arch, f->regs);
|
||||
Rng1U64 frame_vaddr_range = r1u64(last_stack_top, f_stack_top);
|
||||
Rng1U64 frame_vaddr_range_in_viz = intersect_1u64(frame_vaddr_range, viz_range_bytes);
|
||||
@@ -2896,10 +2898,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory)
|
||||
}
|
||||
|
||||
//- rjf: fill selected thread stack range annotation
|
||||
if(unwind.frames.count > 0)
|
||||
if(call_stack.concrete_frames_count > 0)
|
||||
{
|
||||
U64 stack_base_vaddr = thread->stack_base;
|
||||
U64 stack_top_vaddr = regs_rsp_from_arch_block(thread->arch, unwind.frames.v[0].regs);
|
||||
U64 stack_top_vaddr = regs_rsp_from_arch_block(thread->arch, call_stack.concrete_frames[0]->regs);
|
||||
Rng1U64 stack_vaddr_range = r1u64(stack_base_vaddr, stack_top_vaddr);
|
||||
Rng1U64 stack_vaddr_range_in_viz = intersect_1u64(stack_vaddr_range, viz_range_bytes);
|
||||
if(dim_1u64(stack_vaddr_range_in_viz) != 0)
|
||||
@@ -2954,6 +2956,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory)
|
||||
}
|
||||
di_scope_close(scope);
|
||||
}
|
||||
ctrl_scope_close(ctrl_scope);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
@@ -521,13 +521,14 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e
|
||||
{
|
||||
Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol"));
|
||||
dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" "));
|
||||
CTRL_Scope *ctrl_scope = ctrl_scope_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process);
|
||||
Arch arch = entity->arch;
|
||||
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity);
|
||||
for(U64 idx = 0, limit = 6; idx < unwind.frames.count && idx < limit; idx += 1)
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0);
|
||||
for(U64 idx = 0, limit = 6; idx < call_stack.frames_count && idx < limit; idx += 1)
|
||||
{
|
||||
CTRL_UnwindFrame *f = &unwind.frames.v[unwind.frames.count - 1 - idx];
|
||||
CTRL_CallStackFrame *f = &call_stack.frames[call_stack.frames_count - 1 - idx];
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(arch, f->regs);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
|
||||
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
|
||||
@@ -542,7 +543,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e
|
||||
if(name.size != 0)
|
||||
{
|
||||
dr_fstrs_push_new(arena, &result, ¶ms, name, .size = extras_size, .color = symbol_color);
|
||||
if(idx+1 < unwind.frames.count)
|
||||
if(idx+1 < call_stack.frames_count)
|
||||
{
|
||||
dr_fstrs_push_new(arena, &result, ¶ms, str8_lit(" > "), .color = secondary_color, .size = extras_size);
|
||||
if(idx+1 == limit)
|
||||
@@ -554,6 +555,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e
|
||||
}
|
||||
}
|
||||
di_scope_close(di_scope);
|
||||
ctrl_scope_close(ctrl_scope);
|
||||
}
|
||||
|
||||
//- rjf: modules get debug info status extras
|
||||
|
||||
Reference in New Issue
Block a user