first pass at thread-locals view

This commit is contained in:
Ryan Fleury
2024-01-31 12:24:57 -08:00
parent c8010b7542
commit 8602e5b23e
2 changed files with 169 additions and 1 deletions
+88
View File
@@ -7413,6 +7413,94 @@ df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scop
list.count += 1;
}
}break;
//////////////////////////////
//- rjf: all tlocals -> produce rows for visible range
//
case DF_EvalVizBlockKind_AllThreadLocals:
{
DF_Entity *thread = df_entity_from_handle(ctrl_ctx->thread);
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
U64 thread_rip_unwind_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx->unwind_count);
DF_Entity *module = df_module_from_process_vaddr(process, thread_rip_unwind_vaddr);
for(U64 idx = visible_idx_range.min; idx < visible_idx_range.max; idx += 1)
{
// rjf: unpack global info
RADDBG_ThreadVariable *thread_var = raddbg_element_from_idx(parse_ctx->rdbg, thread_variables, idx);
RADDBG_TypeNode *type_node = raddbg_element_from_idx(parse_ctx->rdbg, type_nodes, thread_var->type_idx);
U64 name_size = 0;
U8 *name_base = raddbg_string_from_idx(parse_ctx->rdbg, thread_var->name_string_idx, &name_size);
String8 name = str8(name_base, name_size);
// rjf: get keys for this row
DF_ExpandKey parent_key = block->parent_key;
DF_ExpandKey key = block->key;
key.child_num = idx+1;
// rjf: get eval for this tlocal
DF_Eval eval = df_eval_from_string(arena, scope, ctrl_ctx, parse_ctx, name);
// rjf: get view rules
String8 view_rule_string = df_eval_view_rule_from_key(eval_view, key);
DF_CfgTable view_rule_table = df_cfg_table_from_inheritance(scratch.arena, &block->cfg_table);
df_cfg_table_push_unparsed_string(scratch.arena, &view_rule_table, view_rule_string, DF_CfgSrc_User);
// rjf: apply view rules to eval
{
eval = df_dynamically_typed_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval);
eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, eval, &view_rule_table);
}
// rjf: build row
String8List display_strings = df_single_line_eval_value_strings_from_eval(scratch.arena, DF_EvalVizStringFlag_ReadOnlyDisplayRules, parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, default_radix, font, font_size, 500, 0, eval, &view_rule_table);
String8List edit_strings = df_single_line_eval_value_strings_from_eval(scratch.arena, 0, parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, default_radix, font, font_size, 500, 0, eval, &view_rule_table);
DF_EvalVizRow *row = push_array(arena, DF_EvalVizRow, 1);
row->eval = eval;
row->expr = name;
row->display_value = str8_list_join(arena, &display_strings, 0);
row->edit_value = str8_list_join(arena, &edit_strings, 0);
row->value_ui_rule_node = value_ui_rule_node;
row->value_ui_rule_spec = value_ui_rule_spec;
row->expand_ui_rule_node = expand_ui_rule_node;
row->expand_ui_rule_spec = expand_ui_rule_spec;
if(tg_kind_from_key(eval.type_key) != TG_Kind_Null)
{
for(TG_Key t = eval.type_key;; t = tg_unwrapped_direct_from_graph_raddbg_key(parse_ctx->type_graph, parse_ctx->rdbg, t))
{
TG_Kind kind = tg_kind_from_key(t);
if(kind == TG_Kind_Null)
{
break;
}
if(block->eval.mode != EVAL_EvalMode_NULL && ((TG_Kind_FirstBasic <= kind && kind <= TG_Kind_LastBasic) || kind == TG_Kind_Ptr || kind == TG_Kind_LRef || kind == TG_Kind_RRef))
{
row->flags |= DF_EvalVizRowFlag_CanEditValue;
}
if(expandability_required ||
kind == TG_Kind_Struct ||
kind == TG_Kind_Union ||
kind == TG_Kind_Class ||
kind == TG_Kind_Array)
{
row->flags |= DF_EvalVizRowFlag_CanExpand;
}
if(row->flags & DF_EvalVizRowFlag_CanExpand)
{
break;
}
if(block->eval.mode == EVAL_EvalMode_NULL)
{
break;
}
}
}
row->depth = block->depth;
row->parent_key = parent_key;
row->key = key;
SLLQueuePush(list.first, list.last, row);
list.count += 1;
}
}break;
}
}
scratch_end(scratch);
+81 -1
View File
@@ -822,7 +822,84 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
//
case DF_EvalWatchViewFillKind_ThreadLocals:
{
// TODO(rjf)
// rjf: unpack
DF_Entity *thread = df_entity_from_handle(ctrl_ctx->thread);
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
U64 thread_rip_unwind_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx->unwind_count);
DF_Entity *module = df_module_from_process_vaddr(process, thread_rip_unwind_vaddr);
// rjf: build block for all tlocals
DF_ExpandKey parent_key = df_expand_key_make(5381, 0);
DF_ExpandKey root_key = df_expand_key_make(df_hash_from_expand_key(parent_key), 0);
RADDBG_Parsed *rdbg = parse_ctx->rdbg;
DF_EvalVizBlock *tlocals_block = push_array(arena, DF_EvalVizBlock, 1);
SLLQueuePush(blocks.first, blocks.last, tlocals_block);
tlocals_block->kind = DF_EvalVizBlockKind_AllThreadLocals;
tlocals_block->visual_idx_range = tlocals_block->semantic_idx_range = r1u64(1, rdbg->thread_variables_count);
tlocals_block->parent_key = parent_key;
tlocals_block->key = root_key;
blocks.count += 1;
blocks.total_visual_row_count += dim_1u64(tlocals_block->visual_idx_range);
blocks.total_semantic_row_count += dim_1u64(tlocals_block->semantic_idx_range);
// rjf: split tlocals block per-expansion
df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, df_expand_key_zero(), parent_key, 1);
DF_ExpandNode *root_node = df_expand_node_from_key(&eval_view->expand_tree_table, parent_key);
for(DF_ExpandNode *child = root_node->first; child != 0; child = child->next)
{
U64 child_num = child->key.child_num;
U64 child_idx = child_num-1;
if(child_idx >= rdbg->thread_variables_count)
{
continue;
}
// rjf: truncate existing memblock
tlocals_block->visual_idx_range.max = child_idx;
tlocals_block->semantic_idx_range.max = child_idx;
// rjf: build inheriting cfg table
DF_CfgTable child_cfg = {0};
{
String8 view_rule_string = df_eval_view_rule_from_key(eval_view, df_expand_key_make(df_hash_from_expand_key(parent_key), child_num));
if(view_rule_string.size != 0)
{
df_cfg_table_push_unparsed_string(arena, &child_cfg, view_rule_string, DF_CfgSrc_User);
}
}
// rjf: unpack tlocal
RADDBG_ThreadVariable *thread_var = raddbg_element_from_idx(parse_ctx->rdbg, thread_variables, child_idx);
RADDBG_TypeNode *type_node = raddbg_element_from_idx(parse_ctx->rdbg, type_nodes, thread_var->type_idx);
U64 name_size = 0;
U8 *name_base = raddbg_string_from_idx(parse_ctx->rdbg, thread_var->name_string_idx, &name_size);
String8 name = str8(name_base, name_size);
// rjf: produce eval for the expanded tlocal
DF_Eval eval = df_eval_from_string(arena, scope, ctrl_ctx, parse_ctx, name);
// rjf: recurse for sub-block
{
blocks.total_visual_row_count -= 1;
blocks.total_semantic_row_count -= 1;
df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, parent_key, child->key, name, eval, &child_cfg, 0, &blocks);
}
// rjf: make new memblock for remainder (if any)
if(child_idx+1 < rdbg->thread_variables_count)
{
DF_EvalVizBlock *next_tlocals_block = push_array(arena, DF_EvalVizBlock, 1);
next_tlocals_block->kind = DF_EvalVizBlockKind_AllThreadLocals;
next_tlocals_block->visual_idx_range = r1u64(child_idx+1, rdbg->thread_variables_count);
next_tlocals_block->semantic_idx_range= r1u64(child_idx+1, rdbg->thread_variables_count);
next_tlocals_block->depth = 0;
next_tlocals_block->parent_key = parent_key;
next_tlocals_block->key = root_key;
SLLQueuePush(blocks.first, blocks.last, next_tlocals_block);
blocks.count += 1;
tlocals_block = next_tlocals_block;
}
}
}break;
////////////////////////////
@@ -6807,6 +6884,9 @@ DF_VIEW_CMD_FUNCTION_DEF(ThreadLocals) {}
DF_VIEW_UI_FUNCTION_DEF(ThreadLocals)
{
ProfBeginFunction();
DF_EvalWatchViewState *ewv = df_view_user_state(view, DF_EvalWatchViewState);
df_eval_watch_view_init(ewv, view, DF_EvalWatchViewFillKind_ThreadLocals);
df_eval_watch_view_build(ws, panel, view, ewv, 0, 10, rect);
ProfEnd();
}