proper inline frame unwind selection & storage & command parameterization

This commit is contained in:
Ryan Fleury
2024-06-13 15:18:29 -07:00
parent 2c7d15de59
commit 41e99bd2f6
8 changed files with 255 additions and 125 deletions
+133 -43
View File
@@ -1110,6 +1110,16 @@ df_cmd_params_apply_spec_query(Arena *arena, DF_CtrlCtx *ctrl_ctx, DF_CmdParams
params->index = u64;
df_cmd_params_mark_slot(params, DF_CmdParamSlot_Index);
}break;
case DF_CmdParamSlot_BaseUnwindIndex:
{
params->base_unwind_index = u64;
df_cmd_params_mark_slot(params, DF_CmdParamSlot_BaseUnwindIndex);
}break;
case DF_CmdParamSlot_InlineUnwindIndex:
{
params->inline_unwind_index = u64;
df_cmd_params_mark_slot(params, DF_CmdParamSlot_InlineUnwindIndex);
}break;
case DF_CmdParamSlot_ID:
{
params->id = u64;
@@ -2853,7 +2863,7 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
Rng1U64 line_vaddr_rng = {0};
{
U64 ip_voff = df_voff_from_vaddr(module, ip_vaddr);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, ip_voff);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, ip_voff, 0);
Rng1U64 line_voff_rng = line_info.voff_range;
if(line_voff_rng.max != 0)
{
@@ -2867,7 +2877,7 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
// is enabled. This is enabled by default normally.
{
U64 opl_line_voff_rng = df_voff_from_vaddr(module, line_vaddr_rng.max);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, opl_line_voff_rng);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, opl_line_voff_rng, 0);
if(line_info.pt.line == 0xf00f00 || line_info.pt.line == 0xfeefee)
{
line_vaddr_rng.max = df_vaddr_from_voff(module, line_info.voff_range.max);
@@ -2978,7 +2988,7 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
Rng1U64 line_vaddr_rng = {0};
{
U64 ip_voff = df_voff_from_vaddr(module, ip_vaddr);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, ip_voff);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, ip_voff, 0);
Rng1U64 line_voff_rng = line_info.voff_range;
if(line_voff_rng.max != 0)
{
@@ -2992,7 +3002,7 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
// is enabled. This is enabled by default normally.
{
U64 opl_line_voff_rng = df_voff_from_vaddr(module, line_vaddr_rng.max);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, opl_line_voff_rng);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, opl_line_voff_rng, 0);
if(line_info.pt.line == 0xf00f00 || line_info.pt.line == 0xfeefee)
{
line_vaddr_rng.max = df_vaddr_from_voff(module, line_info.voff_range.max);
@@ -3309,7 +3319,7 @@ df_text_line_src2dasm_info_list_array_from_src_line_range(Arena *arena, DF_Entit
//- rjf: voff -> src lookups
internal DF_TextLineDasm2SrcInfo
df_text_line_dasm2src_info_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff)
df_text_line_dasm2src_info_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff, U64 inline_unwind_idx)
{
Temp scratch = scratch_begin(0, 0);
DI_Scope *scope = di_scope_open();
@@ -3317,16 +3327,33 @@ df_text_line_dasm2src_info_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff)
DF_TextLineDasm2SrcInfo result = {0};
result.file = &df_g_nil_entity;
{
U64 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, voff);
RDI_Unit *unit = rdi_element_from_name_idx(rdi, Units, unit_idx);
RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, unit->line_table_idx);
RDI_ParsedLineTable unit_line_info = {0};
rdi_parsed_from_line_table(rdi, line_table, &unit_line_info);
U64 line_info_idx = rdi_line_info_idx_from_voff(&unit_line_info, voff);
if(line_info_idx < unit_line_info.count)
RDI_Unit *unit = rdi_unit_from_voff(rdi, voff);
RDI_LineTable *line_table = rdi_line_table_from_unit(rdi, unit);
RDI_Scope *scope = rdi_scope_from_voff(rdi, voff);
{
RDI_Line *line = &unit_line_info.lines[line_info_idx];
RDI_Column *column = (line_info_idx < unit_line_info.col_count) ? &unit_line_info.cols[line_info_idx] : 0;
U64 idx = 0;
for(RDI_Scope *s = scope;
s->inline_site_idx != 0 && idx < inline_unwind_idx;
s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx), idx += 1)
{
if(idx == inline_unwind_idx)
{
RDI_InlineSite *inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx);
if(inline_site->line_table_idx != 0)
{
line_table = rdi_element_from_name_idx(rdi, LineTables, inline_site->line_table_idx);
}
break;
}
}
}
RDI_ParsedLineTable parsed_line_table = {0};
rdi_parsed_from_line_table(rdi, line_table, &parsed_line_table);
U64 line_info_idx = rdi_line_info_idx_from_voff(&parsed_line_table, voff);
if(line_info_idx < parsed_line_table.count)
{
RDI_Line *line = &parsed_line_table.lines[line_info_idx];
RDI_Column *column = (line_info_idx < parsed_line_table.col_count) ? &parsed_line_table.cols[line_info_idx] : 0;
RDI_SourceFile *file = rdi_element_from_name_idx(rdi, SourceFiles, line->file_idx);
String8 file_normalized_full_path = {0};
file_normalized_full_path.str = rdi_string_from_idx(rdi, file->normal_full_path_string_idx, &file_normalized_full_path.size);
@@ -3336,7 +3363,7 @@ df_text_line_dasm2src_info_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff)
result.file = df_entity_from_path(file_normalized_full_path, DF_EntityFromPathFlag_All);
}
result.pt = txt_pt(line->line_num, column ? column->col_first : 1);
result.voff_range = r1u64(unit_line_info.voffs[line_info_idx], unit_line_info.voffs[line_info_idx+1]);
result.voff_range = r1u64(parsed_line_table.voffs[line_info_idx], parsed_line_table.voffs[line_info_idx+1]);
}
}
di_scope_close(scope);
@@ -3671,6 +3698,7 @@ df_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, DF_Entity *process,
RDI_Scope *scope = rdi_scope_from_voff(rdi, rip_voff);
// rjf: add rich frames for inlines
U64 inline_unwind_idx = 0;
for(RDI_Scope *s = scope; s->inline_site_idx != 0; s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx))
{
RDI_InlineSite *site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx);
@@ -3681,6 +3709,9 @@ df_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, DF_Entity *process,
n->v.rdi = rdi;
n->v.procedure = 0;
n->v.inline_site = site;
n->v.base_unwind_idx = base_frame_idx;
n->v.inline_unwind_idx = inline_unwind_idx;
inline_unwind_idx += 1;
}
// rjf: add frame for concrete frame
@@ -3691,6 +3722,9 @@ df_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, DF_Entity *process,
n->v.rdi = rdi;
n->v.procedure = rdi_element_from_name_idx(rdi, Procedures, scope->proc_idx);
n->v.inline_site = 0;
n->v.base_unwind_idx = base_frame_idx;
n->v.inline_unwind_idx = inline_unwind_idx;
inline_unwind_idx = 0;
}
DF_Unwind result = {0};
{
@@ -3706,6 +3740,24 @@ df_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, DF_Entity *process,
return result;
}
internal DF_UnwindFrame *
df_frame_from_unwind_idxs(DF_Unwind *unwind, U64 base_unwind_idx, U64 inline_unwind_idx)
{
DF_UnwindFrame *f = 0;
for(U64 idx = 0; idx < unwind->frames.count; idx += 1)
{
if(unwind->frames.v[idx].base_unwind_idx == base_unwind_idx)
{
f = &unwind->frames.v[idx];
if(unwind->frames.v[idx].inline_unwind_idx == inline_unwind_idx)
{
break;
}
}
}
return f;
}
////////////////////////////////
//~ rjf: Entity -> Log Entities
@@ -3882,6 +3934,7 @@ df_ctrl_run(DF_RunKind run, DF_Entity *run_thread, CTRL_RunFlags flags, CTRL_Tra
// rjf: set control context to top unwind
df_state->ctrl_ctx.unwind_count = 0;
df_state->ctrl_ctx.inline_unwind_count = 0;
scratch_end(scratch);
}
@@ -6506,13 +6559,15 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec)
{
log_infof("| cmd_spec: \"%S\"\n", params->cmd_spec->info.string);
}
if(params->string.size != 0) { log_infof("| string: \"%S\"\n", params->string); }
if(params->file_path.size != 0) { log_infof("| file_path: \"%S\"\n", params->file_path); }
if(params->text_point.line != 0){ log_infof("| text_point: [line:%I64d, col:%I64d]\n", params->text_point.line, params->text_point.column); }
if(params->vaddr != 0) { log_infof("| vaddr: 0x%I64x\n", params->vaddr); }
if(params->voff != 0) { log_infof("| voff: 0x%I64x\n", params->voff); }
if(params->index != 0) { log_infof("| index: 0x%I64x\n", params->index); }
if(params->id != 0) { log_infof("| id: 0x%I64x\n", params->id); }
if(params->string.size != 0) { log_infof("| string: \"%S\"\n", params->string); }
if(params->file_path.size != 0) { log_infof("| file_path: \"%S\"\n", params->file_path); }
if(params->text_point.line != 0) { log_infof("| text_point: [line:%I64d, col:%I64d]\n", params->text_point.line, params->text_point.column); }
if(params->vaddr != 0) { log_infof("| vaddr: 0x%I64x\n", params->vaddr); }
if(params->voff != 0) { log_infof("| voff: 0x%I64x\n", params->voff); }
if(params->index != 0) { log_infof("| index: 0x%I64x\n", params->index); }
if(params->base_unwind_index != 0) { log_infof("| base_unwind_index: 0x%I64x\n", params->base_unwind_index); }
if(params->inline_unwind_index != 0){ log_infof("| inline_unwind_index: 0x%I64x\n", params->inline_unwind_index); }
if(params->id != 0) { log_infof("| id: 0x%I64x\n", params->id); }
if(params->os_event != 0)
{
String8 kind_string = str8_lit("<unknown>");
@@ -6786,7 +6841,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
DF_Entity *module = df_module_from_process_vaddr(process, stop_thread_vaddr);
DI_Key dbgi_key = df_dbgi_key_from_module(module);
U64 stop_thread_voff = df_voff_from_vaddr(module, stop_thread_vaddr);
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, stop_thread_voff);
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, stop_thread_voff, 0);
DF_EntityList user_bps = df_query_cached_entity_list_with_kind(DF_EntityKind_Breakpoint);
for(DF_EntityNode *n = user_bps.first; n != 0; n = n->next)
{
@@ -7623,32 +7678,67 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
}break;
case DF_CoreCmdKind_SelectUnwind:
{
DI_Scope *di_scope = di_scope_open();
DF_Entity *thread = df_entity_from_handle(df_state->ctrl_ctx.thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
U64 max_unwind = unwind.frames.count ? unwind.frames.count-1 : 0;
U64 index = Clamp(0, params.index, max_unwind);
df_state->ctrl_ctx.unwind_count = index;
df_state->ctrl_ctx.inline_unwind_count = 0;
}break;
case DF_CoreCmdKind_SelectInlineUnwind:
{
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
CTRL_Unwind base_unwind = df_query_cached_unwind_from_thread(thread);
DF_Unwind rich_unwind = df_unwind_from_ctrl_unwind(scratch.arena, di_scope, process, &base_unwind);
DF_UnwindFrame *frame = df_frame_from_unwind_idxs(&rich_unwind, params.base_unwind_index, params.inline_unwind_index);
if(frame != 0)
{
df_state->ctrl_ctx.unwind_count = frame->base_unwind_idx;
df_state->ctrl_ctx.inline_unwind_count = frame->inline_unwind_idx;
}
di_scope_close(di_scope);
}break;
case DF_CoreCmdKind_UpOneFrame:
{
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx();
DF_CmdParams p = params;
p.index = (ctrl_ctx.unwind_count > 0 ? ctrl_ctx.unwind_count - 1 : 0);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Index);
df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectUnwind));
}break;
case DF_CoreCmdKind_DownOneFrame:
{
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx();
DF_CmdParams p = params;
p.index = ctrl_ctx.unwind_count+1;
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Index);
df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectUnwind));
DI_Scope *di_scope = di_scope_open();
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
CTRL_Unwind base_unwind = df_query_cached_unwind_from_thread(thread);
DF_Unwind rich_unwind = df_unwind_from_ctrl_unwind(scratch.arena, di_scope, process, &base_unwind);
DF_UnwindFrame *current_frame = 0;
for(U64 idx = 0; idx < rich_unwind.frames.count; idx += 1)
{
if(rich_unwind.frames.v[idx].base_unwind_idx == ctrl_ctx.unwind_count &&
rich_unwind.frames.v[idx].inline_unwind_idx == ctrl_ctx.inline_unwind_count)
{
current_frame = &rich_unwind.frames.v[idx];
break;
}
}
if(current_frame == 0 && rich_unwind.frames.count != 0)
{
current_frame = &rich_unwind.frames.v[0];
}
DF_UnwindFrame *next_frame = current_frame;
switch(core_cmd_kind)
{
default:{}break;
case DF_CoreCmdKind_UpOneFrame:
if(current_frame != 0 && (current_frame - rich_unwind.frames.v) > 0)
{
next_frame -= 1;
}break;
case DF_CoreCmdKind_DownOneFrame:
if(current_frame != 0 && (current_frame - rich_unwind.frames.v)+1 < rich_unwind.frames.count)
{
next_frame += 1;
}break;
}
if(next_frame != 0)
{
DF_CmdParams p = params;
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_BaseUnwindIndex);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_InlineUnwindIndex);
p.base_unwind_index = next_frame->base_unwind_idx;
p.inline_unwind_index = next_frame->base_unwind_idx;
df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectUnwind));
}
di_scope_close(di_scope);
}break;
case DF_CoreCmdKind_FreezeThread:
case DF_CoreCmdKind_ThawThread: