d regs -> mdesk

This commit is contained in:
Ryan Fleury
2024-08-30 10:07:56 -07:00
parent ecf9cd1dab
commit 13f2de6e88
7 changed files with 279 additions and 126 deletions
+56 -1
View File
@@ -88,6 +88,62 @@ D_EntityKindTable:
{EndedProcess ended_process ended_processes 1 0 0 1 0 0 0 0 0 0 0 "Label" Null "EndedProcess" }
}
////////////////////////////////
//~ rjf: Registers Type Table
@table(c_type name_lower name)
D_RegTable:
{
// rjf: entity slots
{D_Handle module Module }
{D_Handle process Process }
{D_Handle thread Thread }
{D_Handle window Window }
{D_Handle panel Panel }
{D_Handle view View }
{D_Handle prev_view PrevView }
{D_Handle dst_panel DstPanel }
{D_Handle entity Entity }
{D_HandleList entity_list EntityList }
// rjf: frame selection
{U64 unwind_count UnwindCount }
{U64 inline_depth InlineDepth }
// rjf: code / address location info
{String8 file_path FilePath }
{TxtPt cursor Cursor }
{TxtPt mark Mark }
{U128 text_key TextKey }
{TXT_LangKind lang_kind LangKind }
{D_LineList lines Lines }
{DI_Key dbgi_key DbgiKey }
{Rng1U64 vaddr_range VaddrRange }
{Rng1U64 voff_range VoffRange }
// rjf: general parameters
{B32 force_confirm ForceConfirm }
{B32 prefer_disasm PreferDisasm }
{Dir2 dir2 Dir2 }
{String8 string String }
{`MD_Node *` params_tree ParamsTree }
}
@enum D_RegSlot:
{
@expand(D_RegTable a) `$(a.name)`
}
@struct D_Regs:
{
@expand(D_RegTable a) `$(a.c_type) $(a.name_lower)`
}
@data(Rng1U64) d_reg_slot_range_table:
{
@expand(D_RegTable a) `{OffsetOf(D_Regs, $(a.name_lower)), OffsetOf(D_Regs, $(a.name_lower)) + sizeof($(a.c_type))}`
}
////////////////////////////////
//~ rjf: Built-In Command Tables
@@ -613,7 +669,6 @@ DF_DevToggleTable:
@data(Rng1U64) d_cmd_param_slot_range_table:
{
`{0}`,
@expand(D_CmdParamSlotTable a) `{OffsetOf(D_CmdParams, $(a.name_lower)), OffsetOf(D_CmdParams, $(a.name_lower)) + sizeof($(a.c_type))}`,
}
+25 -4
View File
@@ -100,7 +100,7 @@ d_handle_list_find(D_HandleList *list, D_Handle handle)
}
internal D_HandleList
d_push_handle_list_copy(Arena *arena, D_HandleList list)
d_handle_list_copy(Arena *arena, D_HandleList list)
{
D_HandleList result = {0};
for(D_HandleNode *n = list.first; n != 0; n = n->next)
@@ -110,6 +110,29 @@ d_push_handle_list_copy(Arena *arena, D_HandleList list)
return result;
}
////////////////////////////////
//~ rjf: Registers Type Pure Functions
internal void
d_regs_copy_contents(Arena *arena, D_Regs *dst, D_Regs *src)
{
MemoryCopyStruct(dst, src);
dst->entity_list = d_handle_list_copy(arena, src->entity_list);
dst->file_path = push_str8_copy(arena, src->file_path);
dst->lines = d_line_list_copy(arena, &src->lines);
dst->dbgi_key = di_key_copy(arena, &src->dbgi_key);
dst->string = push_str8_copy(arena, src->string);
dst->params_tree = md_tree_copy(arena, src->params_tree);
}
internal D_Regs *
d_regs_copy(Arena *arena, D_Regs *src)
{
D_Regs *dst = push_array(arena, D_Regs, 1);
d_regs_copy_contents(arena, dst, src);
return dst;
}
////////////////////////////////
//~ rjf: State History Data Structure
@@ -6351,9 +6374,7 @@ d_begin_frame(Arena *arena, D_CmdList *cmds, F32 dt)
d_state->dt = dt;
d_state->time_in_seconds += dt;
d_state->top_regs = &d_state->base_regs;
d_state->top_regs->v.file_path = push_str8_copy(d_frame_arena(), d_state->top_regs->v.file_path);
d_state->top_regs->v.lines = d_line_list_copy(d_frame_arena(), &d_state->top_regs->v.lines);
d_state->top_regs->v.dbgi_key = di_key_copy(d_frame_arena(), &d_state->top_regs->v.dbgi_key);
d_regs_copy_contents(d_frame_arena(), &d_state->top_regs->v, &d_state->top_regs->v);
//- rjf: sync with ctrl thread
ProfScope("sync with ctrl thread")
+43 -59
View File
@@ -29,6 +29,41 @@ struct D_HandleList
U64 count;
};
////////////////////////////////
//~ rjf: Line Info Types
typedef struct D_Line D_Line;
struct D_Line
{
String8 file_path;
TxtPt pt;
Rng1U64 voff_range;
DI_Key dbgi_key;
};
typedef struct D_LineNode D_LineNode;
struct D_LineNode
{
D_LineNode *next;
D_Line v;
};
typedef struct D_LineList D_LineList;
struct D_LineList
{
D_LineNode *first;
D_LineNode *last;
U64 count;
};
typedef struct D_LineListArray D_LineListArray;
struct D_LineListArray
{
D_LineList *v;
U64 count;
DI_KeyList dbgi_keys;
};
////////////////////////////////
//~ rjf: Sparse Tree Expansion State Data Structure
@@ -401,64 +436,7 @@ struct D_Unwind
};
////////////////////////////////
//~ rjf: Line Info Types
typedef struct D_Line D_Line;
struct D_Line
{
String8 file_path;
TxtPt pt;
Rng1U64 voff_range;
DI_Key dbgi_key;
};
typedef struct D_LineNode D_LineNode;
struct D_LineNode
{
D_LineNode *next;
D_Line v;
};
typedef struct D_LineList D_LineList;
struct D_LineList
{
D_LineNode *first;
D_LineNode *last;
U64 count;
};
typedef struct D_LineListArray D_LineListArray;
struct D_LineListArray
{
D_LineList *v;
U64 count;
DI_KeyList dbgi_keys;
};
////////////////////////////////
//~ rjf: Interaction Context Register Types
typedef struct D_Regs D_Regs;
struct D_Regs
{
D_Handle module;
D_Handle process;
D_Handle thread;
U64 unwind_count;
U64 inline_depth;
D_Handle window;
D_Handle panel;
D_Handle view;
String8 file_path;
TxtPt cursor;
TxtPt mark;
U128 text_key;
TXT_LangKind lang_kind;
Rng1U64 vaddr_range;
Rng1U64 voff_range;
D_LineList lines;
DI_Key dbgi_key;
};
//~ rjf: Context Register Types
typedef struct D_RegsNode D_RegsNode;
struct D_RegsNode
@@ -1110,7 +1088,13 @@ internal void d_handle_list_push_node(D_HandleList *list, D_HandleNode *node);
internal void d_handle_list_push(Arena *arena, D_HandleList *list, D_Handle handle);
internal void d_handle_list_remove(D_HandleList *list, D_HandleNode *node);
internal D_HandleNode *d_handle_list_find(D_HandleList *list, D_Handle handle);
internal D_HandleList d_push_handle_list_copy(Arena *arena, D_HandleList list);
internal D_HandleList d_handle_list_copy(Arena *arena, D_HandleList list);
////////////////////////////////
//~ rjf: Registers Type Pure Functions
internal void d_regs_copy_contents(Arena *arena, D_Regs *dst, D_Regs *src);
internal D_Regs *d_regs_copy(Arena *arena, D_Regs *src);
////////////////////////////////
//~ rjf: State History Data Structure
+31 -2
View File
@@ -4,9 +4,38 @@
//- GENERATED CODE
C_LINKAGE_BEGIN
Rng1U64 d_cmd_param_slot_range_table[24] =
Rng1U64 d_reg_slot_range_table[26] =
{
{OffsetOf(D_Regs, module), OffsetOf(D_Regs, module) + sizeof(D_Handle)},
{OffsetOf(D_Regs, process), OffsetOf(D_Regs, process) + sizeof(D_Handle)},
{OffsetOf(D_Regs, thread), OffsetOf(D_Regs, thread) + sizeof(D_Handle)},
{OffsetOf(D_Regs, window), OffsetOf(D_Regs, window) + sizeof(D_Handle)},
{OffsetOf(D_Regs, panel), OffsetOf(D_Regs, panel) + sizeof(D_Handle)},
{OffsetOf(D_Regs, view), OffsetOf(D_Regs, view) + sizeof(D_Handle)},
{OffsetOf(D_Regs, prev_view), OffsetOf(D_Regs, prev_view) + sizeof(D_Handle)},
{OffsetOf(D_Regs, dst_panel), OffsetOf(D_Regs, dst_panel) + sizeof(D_Handle)},
{OffsetOf(D_Regs, entity), OffsetOf(D_Regs, entity) + sizeof(D_Handle)},
{OffsetOf(D_Regs, entity_list), OffsetOf(D_Regs, entity_list) + sizeof(D_HandleList)},
{OffsetOf(D_Regs, unwind_count), OffsetOf(D_Regs, unwind_count) + sizeof(U64)},
{OffsetOf(D_Regs, inline_depth), OffsetOf(D_Regs, inline_depth) + sizeof(U64)},
{OffsetOf(D_Regs, file_path), OffsetOf(D_Regs, file_path) + sizeof(String8)},
{OffsetOf(D_Regs, cursor), OffsetOf(D_Regs, cursor) + sizeof(TxtPt)},
{OffsetOf(D_Regs, mark), OffsetOf(D_Regs, mark) + sizeof(TxtPt)},
{OffsetOf(D_Regs, text_key), OffsetOf(D_Regs, text_key) + sizeof(U128)},
{OffsetOf(D_Regs, lang_kind), OffsetOf(D_Regs, lang_kind) + sizeof(TXT_LangKind)},
{OffsetOf(D_Regs, lines), OffsetOf(D_Regs, lines) + sizeof(D_LineList)},
{OffsetOf(D_Regs, dbgi_key), OffsetOf(D_Regs, dbgi_key) + sizeof(DI_Key)},
{OffsetOf(D_Regs, vaddr_range), OffsetOf(D_Regs, vaddr_range) + sizeof(Rng1U64)},
{OffsetOf(D_Regs, voff_range), OffsetOf(D_Regs, voff_range) + sizeof(Rng1U64)},
{OffsetOf(D_Regs, force_confirm), OffsetOf(D_Regs, force_confirm) + sizeof(B32)},
{OffsetOf(D_Regs, prefer_disasm), OffsetOf(D_Regs, prefer_disasm) + sizeof(B32)},
{OffsetOf(D_Regs, dir2), OffsetOf(D_Regs, dir2) + sizeof(Dir2)},
{OffsetOf(D_Regs, string), OffsetOf(D_Regs, string) + sizeof(String8)},
{OffsetOf(D_Regs, params_tree), OffsetOf(D_Regs, params_tree) + sizeof(MD_Node *)},
};
Rng1U64 d_cmd_param_slot_range_table[23] =
{
{0},
{OffsetOf(D_CmdParams, window), OffsetOf(D_CmdParams, window) + sizeof(D_Handle)},
{OffsetOf(D_CmdParams, panel), OffsetOf(D_CmdParams, panel) + sizeof(D_Handle)},
{OffsetOf(D_CmdParams, dest_panel), OffsetOf(D_CmdParams, dest_panel) + sizeof(D_Handle)},
+63 -1
View File
@@ -6,6 +6,36 @@
#ifndef DBG_ENGINE_META_H
#define DBG_ENGINE_META_H
typedef enum D_RegSlot
{
D_RegSlot_Module,
D_RegSlot_Process,
D_RegSlot_Thread,
D_RegSlot_Window,
D_RegSlot_Panel,
D_RegSlot_View,
D_RegSlot_PrevView,
D_RegSlot_DstPanel,
D_RegSlot_Entity,
D_RegSlot_EntityList,
D_RegSlot_UnwindCount,
D_RegSlot_InlineDepth,
D_RegSlot_FilePath,
D_RegSlot_Cursor,
D_RegSlot_Mark,
D_RegSlot_TextKey,
D_RegSlot_LangKind,
D_RegSlot_Lines,
D_RegSlot_DbgiKey,
D_RegSlot_VaddrRange,
D_RegSlot_VoffRange,
D_RegSlot_ForceConfirm,
D_RegSlot_PreferDisasm,
D_RegSlot_Dir2,
D_RegSlot_String,
D_RegSlot_ParamsTree,
} D_RegSlot;
typedef enum D_CfgSrc
{
D_CfgSrc_User,
@@ -332,6 +362,37 @@ D_CmdParamSlot_InlineDepth,
D_CmdParamSlot_COUNT,
} D_CmdParamSlot;
typedef struct D_Regs D_Regs;
struct D_Regs
{
D_Handle module;
D_Handle process;
D_Handle thread;
D_Handle window;
D_Handle panel;
D_Handle view;
D_Handle prev_view;
D_Handle dst_panel;
D_Handle entity;
D_HandleList entity_list;
U64 unwind_count;
U64 inline_depth;
String8 file_path;
TxtPt cursor;
TxtPt mark;
U128 text_key;
TXT_LangKind lang_kind;
D_LineList lines;
DI_Key dbgi_key;
Rng1U64 vaddr_range;
Rng1U64 voff_range;
B32 force_confirm;
B32 prefer_disasm;
Dir2 dir2;
String8 string;
MD_Node * params_tree;
};
typedef struct D_CmdParams D_CmdParams;
struct D_CmdParams
{
@@ -399,7 +460,8 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =
{&DEV_updating_indicator, str8_lit_comp("updating_indicator")},
};
C_LINKAGE_BEGIN
extern Rng1U64 d_cmd_param_slot_range_table[24];
extern Rng1U64 d_reg_slot_range_table[26];
extern Rng1U64 d_cmd_param_slot_range_table[23];
extern String8 d_entity_kind_display_string_table[31];
extern String8 d_entity_kind_name_lower_table[31];
extern String8 d_entity_kind_name_lower_plural_table[31];
+1 -1
View File
@@ -488,7 +488,7 @@ df_cmd_params_copy(Arena *arena, D_CmdParams *src)
{
D_CmdParams dst = {0};
MemoryCopyStruct(&dst, src);
dst.entity_list = d_push_handle_list_copy(arena, src->entity_list);
dst.entity_list = d_handle_list_copy(arena, src->entity_list);
if(dst.entity_list.count == 0 && !d_handle_match(src->entity, d_handle_zero()))
{
d_handle_list_push(arena, &dst.entity_list, dst.entity);
+60 -58
View File
@@ -3,47 +3,49 @@
////////////////////////////////
//~ rjf: Frontend/UI Pass Tasks
//
// [ ] engine/frontend commands situation
// - currently, there is an interesting bifurcation of commands in the
// frontend; you can either push a command *at a root level*, or push a
// command to a locally-accessible list if you want that command to run
// on the same frame (root level commands are deferred by a frame, since
// the engine must see them first).
// - things would be simpler if there was only a single "push command"
// mechanism, and codepaths only ever saw these commands at most once.
// this would require an alternate strategy of the initial "gather" of
// commands, and instead it would just be a global queue, or something...
// it is a little weird since commands are not just consumed in order...
// - this will clean up the various different ways that codepaths
// parameterize commands.
// [ ] frontend entities vs. engine entities
// - currently, the engine has entities like "watch", and the frontend
// has entities like "windows", "panels", and "views".
// - because "watch" entities ideally have a hierarchical relationship
// with windows, panels, and views (enabling things like drag/drop
// from watch window -> tab, or tab -> watch window, trivially), it
// would be much better if all entities could collapse into engine
// entities.
// - now, the frontend requires various specialized resources for things
// like windows, so what I am thinking is that the engine just controls
// all of the stateful windows/panel/view/watch mechanisms, and then
// the frontend pure-functionally queries stuff like os/r handles
// on-demand, and then prunes them, immediate-mode cache style.
// [ ] command params -> d_regs
// - currently there are two almost-identical concepts relating to commands:
// the parameters struct, and D_Regs. D_Regs is a registers struct which
// is used to manage a stack of contextual information in various debugger
// codepaths. it is used so that codepaths can register information they
// know about, without passing it down to everyone explicitly - but those
// later codepaths can still pass that information along. e.g. a window
// calls into a watch window, watch window calls into visualizer, visualizer
// pushes command, which needs to pass which window it occurred on along.
// - i think D_Regs needs to expand a bit in order to encompass all of the
// things that the command parameters were being used for, but at that point
// commands can just be a spec * regs, and then the push-command API can
// just have ways of overriding regs values explicitly, when the codepath
// needs to be opinionated about which things are affected by which commands
//
// [ ] empty user file causing failure to launch
//
// [ ] engine/frontend commands situation
// - currently, there is an interesting bifurcation of commands in the
// frontend; you can either push a command *at a root level*, or push a
// command to a locally-accessible list if you want that command to run
// on the same frame (root level commands are deferred by a frame, since
// the engine must see them first).
// - things would be simpler if there was only a single "push command"
// mechanism, and codepaths only ever saw these commands at most once.
// this would require an alternate strategy of the initial "gather" of
// commands, and instead it would just be a global queue, or something...
// it is a little weird since commands are not just consumed in order...
// - this will clean up the various different ways that codepaths
// parameterize commands.
// [ ] frontend entities vs. engine entities
// - currently, the engine has entities like "watch", and the frontend
// has entities like "windows", "panels", and "views".
// - because "watch" entities ideally have a hierarchical relationship
// with windows, panels, and views (enabling things like drag/drop
// from watch window -> tab, or tab -> watch window, trivially), it
// would be much better if all entities could collapse into engine
// entities.
// - now, the frontend requires various specialized resources for things
// like windows, so what I am thinking is that the engine just controls
// all of the stateful windows/panel/view/watch mechanisms, and then
// the frontend pure-functionally queries stuff like os/r handles
// on-demand, and then prunes them, immediate-mode cache style.
// [ ] command params -> d_regs
// - currently there are two almost-identical concepts relating to commands:
// the parameters struct, and D_Regs. D_Regs is a registers struct which
// is used to manage a stack of contextual information in various debugger
// codepaths. it is used so that codepaths can register information they
// know about, without passing it down to everyone explicitly - but those
// later codepaths can still pass that information along. e.g. a window
// calls into a watch window, watch window calls into visualizer, visualizer
// pushes command, which needs to pass which window it occurred on along.
// - i think D_Regs needs to expand a bit in order to encompass all of the
// things that the command parameters were being used for, but at that point
// commands can just be a spec * regs, and then the push-command API can
// just have ways of overriding regs values explicitly, when the codepath
// needs to be opinionated about which things are affected by which commands
//
// [ ] transient view timeout releasing
//
@@ -431,28 +433,28 @@
// against stopper thread's
//
// [x] PDB files distributed with the build are not found by DbgHelp!!!
// [x] Jai compiler debugging crash
//
//- 2024/8/29
// [x] Jai compiler debugging crash
//
//- 2024/8/29
//
// [x] fix HRESULTs
// [x] fix escape char literals
// [x] eval: indexing into string literals
// [x] fix incorrectly consuming keyboard inputs, preventing fallback-to-filtering, when
// selecting null selection in watch views
// selecting null selection in watch views
// [x] ui_next_event(...), built-in focus filtering, no need to manually check
// if(ui_is_focus_active())
// if(ui_is_focus_active())
// [x] Theme window should include font scaling. I was able to find the
// command for increasing the font scale, but I imagine most people
// wouldn't think to look there.
// wouldn't think to look there.
// [x] n-row table selection, in watch window & other UIs, multi-selection
// ctrl+C
// [x] target/breakpoint/watch-pin reordering
// [x] move breakpoints to being a global thing, not nested to particular files
// [x] target/breakpoint/watch-pin reordering
// [x] move breakpoints to being a global thing, not nested to particular files
// [x] EVAL SPACES - each rdi gets an rdi space, rdi space is passed to
// memory reads & so on, used to resolve to value space; REPLACES "mode"
// memory reads & so on, used to resolve to value space; REPLACES "mode"
// [x] fix selecting hover eval, then hover eval disappearing, causing
// busted focus, until a new hover eval is opened
// busted focus, until a new hover eval is opened
// [x] `text[:lang]` - interpret memory as text, in lang `lang`
// [x] `disasm:arch` - interpret memory as machine code for isa `arch`
// [x] `memory` - view memory in usual memory hex-editor view
@@ -461,21 +463,21 @@
// view, or memory view will simply be specializations of the general purpose
// viz system.
// [x] view rule hook for standalone visualization ui, granted its own
// tab
// tab
// [x] collapse frontend visualization systems - source view, disasm view,
// callstack, modules, scheduler, should *all* be flavors of watch view
// [x] globally disable/configure bp/ip lines in source view
// callstack, modules, scheduler, should *all* be flavors of watch view
// [x] globally disable/configure bp/ip lines in source view
// [x] @cleanup naming pass over eval visualization part of the frontend,
// "blocks" vs. "canvas" vs. "expansion" - etc.
// "blocks" vs. "canvas" vs. "expansion" - etc.
// [x] @cleanup collapse DF_CfgNodes into just being MD trees, find another way
// to encode config source - don't need it at every node
// to encode config source - don't need it at every node
// [x] @cleanup in the frontend, we are starting to have to pass down "DF_Window"
// everywhere, because of per-window parameters (e.g. font rendering settings).
// this is really better solved by implicit thread-local parameters, similar to
// interaction registers, so that one window can "pick" all of the implicit
// parameters, and then 99% of the UI code does not have to care.
// parameters, and then 99% of the UI code does not have to care.
// [x] @cleanup simplification pass over eval visualization pipeline & types,
// including view rule hooks
// including view rule hooks
#ifndef RADDBG_H
#define RADDBG_H