mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-20 23:46:48 +00:00
tear out old meta evaluation code; robustify filesystem streaming async reads
This commit is contained in:
+100
-84
@@ -216,7 +216,6 @@ ctrl_msg_deep_copy(Arena *arena, CTRL_Msg *dst, CTRL_Msg *src)
|
||||
dst->env_string_list = str8_list_copy(arena, &src->env_string_list);
|
||||
dst->traps = ctrl_trap_list_copy(arena, &src->traps);
|
||||
dst->user_bps = ctrl_user_breakpoint_list_copy(arena, &src->user_bps);
|
||||
dst->meta_evals = *deep_copy_from_struct(arena, CTRL_MetaEvalArray, &src->meta_evals);
|
||||
}
|
||||
|
||||
//- rjf: list building
|
||||
@@ -347,10 +346,6 @@ ctrl_serialized_string_from_msg_list(Arena *arena, CTRL_MsgList *msgs)
|
||||
str8_serial_push_struct(scratch.arena, &msgs_srlzed, &bp->condition.size);
|
||||
str8_serial_push_data(scratch.arena, &msgs_srlzed, bp->condition.str, bp->condition.size);
|
||||
}
|
||||
|
||||
// rjf: write meta-eval-info array
|
||||
String8 meta_evals_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEvalArray, &msg->meta_evals);
|
||||
str8_serial_push_string(scratch.arena, &msgs_srlzed, meta_evals_srlzed);
|
||||
}
|
||||
}
|
||||
String8 string = str8_serial_end(arena, &msgs_srlzed);
|
||||
@@ -474,12 +469,6 @@ ctrl_msg_list_from_serialized_string(Arena *arena, String8 string)
|
||||
bp->condition.str = push_array_no_zero(arena, U8, bp->condition.size);
|
||||
read_off += str8_deserial_read(string, read_off, bp->condition.str, bp->condition.size, 1);
|
||||
}
|
||||
|
||||
// rjf: read meta-eval-info array
|
||||
String8 meta_evals_data = str8_skip(string, read_off);
|
||||
U64 meta_evals_size = 0;
|
||||
msg->meta_evals = *struct_from_serialized(arena, CTRL_MetaEvalArray, meta_evals_data, .advance_out = &meta_evals_size);
|
||||
read_off += meta_evals_size;
|
||||
}
|
||||
}
|
||||
return msgs;
|
||||
@@ -1320,7 +1309,6 @@ ctrl_init(void)
|
||||
ctrl_state->ctrl_thread_entity_store = ctrl_entity_store_alloc();
|
||||
ctrl_state->dmn_event_arena = arena_alloc();
|
||||
ctrl_state->user_entry_point_arena = arena_alloc();
|
||||
ctrl_state->user_meta_eval_arena = arena_alloc();
|
||||
ctrl_state->dbg_dir_arena = arena_alloc();
|
||||
for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)0; k < CTRL_ExceptionCodeKind_COUNT; k = (CTRL_ExceptionCodeKind)(k+1))
|
||||
{
|
||||
@@ -3009,44 +2997,114 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle threa
|
||||
internal CTRL_CallStack
|
||||
ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
Arch arch = process->arch;
|
||||
CTRL_CallStack result = {0};
|
||||
result.concrete_frame_count = base_unwind->frames.count;
|
||||
result.total_frame_count = result.concrete_frame_count;
|
||||
result.frames = push_array(arena, CTRL_CallStackFrame, result.concrete_frame_count);
|
||||
for(U64 idx = 0; idx < result.concrete_frame_count; idx += 1)
|
||||
{
|
||||
CTRL_UnwindFrame *src = &base_unwind->frames.v[idx];
|
||||
CTRL_CallStackFrame *dst = &result.frames[idx];
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(arch, src->regs);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
|
||||
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
|
||||
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
|
||||
RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0);
|
||||
RDI_Scope *scope = rdi_scope_from_voff(rdi, rip_voff);
|
||||
|
||||
// rjf: fill concrete frame info
|
||||
dst->regs = src->regs;
|
||||
dst->rdi = rdi;
|
||||
dst->procedure = rdi_element_from_name_idx(rdi, Procedures, scope->proc_idx);
|
||||
|
||||
// rjf: push inline frames
|
||||
for(RDI_Scope *s = scope;
|
||||
s->inline_site_idx != 0;
|
||||
s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx))
|
||||
typedef struct FrameNode FrameNode;
|
||||
struct FrameNode
|
||||
{
|
||||
RDI_InlineSite *site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx);
|
||||
CTRL_CallStackInlineFrame *inline_frame = push_array(arena, CTRL_CallStackInlineFrame, 1);
|
||||
DLLPushFront(dst->first_inline_frame, dst->last_inline_frame, inline_frame);
|
||||
inline_frame->inline_site = site;
|
||||
dst->inline_frame_count += 1;
|
||||
result.inline_frame_count += 1;
|
||||
result.total_frame_count += 1;
|
||||
FrameNode *next;
|
||||
CTRL_CallStackFrame v;
|
||||
};
|
||||
|
||||
//- rjf: gather all frames
|
||||
FrameNode *first_frame = 0;
|
||||
FrameNode *last_frame = 0;
|
||||
U64 frame_count = 0;
|
||||
for(U64 base_frame_idx = 0; base_frame_idx < base_unwind->frames.count; base_frame_idx += 1)
|
||||
{
|
||||
// rjf: unpack
|
||||
CTRL_UnwindFrame *src = &base_unwind->frames.v[base_frame_idx];
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(arch, src->regs);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
|
||||
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
|
||||
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
|
||||
RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0);
|
||||
RDI_Scope *scope = rdi_scope_from_voff(rdi, rip_voff);
|
||||
|
||||
// rjf: build inline frames (minus parent & inline depth)
|
||||
FrameNode *first_inline_frame = 0;
|
||||
FrameNode *last_inline_frame = 0;
|
||||
U64 inline_frame_count = 0;
|
||||
for(RDI_Scope *s = scope;
|
||||
s->inline_site_idx != 0;
|
||||
s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx))
|
||||
{
|
||||
FrameNode *dst_inline = push_array(scratch.arena, FrameNode, 1);
|
||||
if(first_inline_frame == 0)
|
||||
{
|
||||
first_inline_frame = dst_inline;
|
||||
}
|
||||
last_inline_frame = dst_inline;
|
||||
SLLQueuePush(first_frame, last_frame, dst_inline);
|
||||
dst_inline->v.unwind_count = base_frame_idx;
|
||||
dst_inline->v.regs = src->regs;
|
||||
dst_inline->v.rdi = rdi;
|
||||
dst_inline->v.inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx);
|
||||
frame_count += 1;
|
||||
inline_frame_count += 1;
|
||||
}
|
||||
|
||||
// rjf: build concrete frame
|
||||
FrameNode *dst_base = push_array(scratch.arena, FrameNode, 1);
|
||||
SLLQueuePush(first_frame, last_frame, dst_base);
|
||||
dst_base->v.unwind_count = base_frame_idx;
|
||||
dst_base->v.regs = src->regs;
|
||||
dst_base->v.rdi = rdi;
|
||||
dst_base->v.procedure = rdi_element_from_name_idx(rdi, Procedures, scope->proc_idx);
|
||||
frame_count += 1;
|
||||
|
||||
// rjf: hook up inline frames to point to concrete frame, and to account for inline depth
|
||||
U64 inline_frame_idx = 0;
|
||||
for(FrameNode *inline_frame = first_inline_frame; inline_frame != 0; inline_frame = inline_frame->next, inline_frame_idx += 1)
|
||||
{
|
||||
inline_frame->v.parent_num = frame_count;
|
||||
inline_frame->v.inline_depth = inline_frame_count - inline_frame_idx;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: package
|
||||
result.count = frame_count;
|
||||
result.frames = push_array(arena, CTRL_CallStackFrame, result.count);
|
||||
{
|
||||
U64 idx = 0;
|
||||
for(FrameNode *n = first_frame; n != 0; n = n->next, idx += 1)
|
||||
{
|
||||
MemoryCopyStruct(&result.frames[idx], &n->v);
|
||||
}
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal CTRL_CallStackFrame *
|
||||
ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U64 unwind_count, U64 inline_depth)
|
||||
{
|
||||
CTRL_CallStackFrame *f = 0;
|
||||
{
|
||||
U64 base_frame_idx = 0;
|
||||
for(U64 idx = 0; idx < call_stack->count; idx += 1)
|
||||
{
|
||||
if(call_stack->frames[idx].parent_num == 0)
|
||||
{
|
||||
if(base_frame_idx == unwind_count)
|
||||
{
|
||||
f = &call_stack->frames[idx];
|
||||
break;
|
||||
}
|
||||
base_frame_idx += 1;
|
||||
}
|
||||
}
|
||||
if(f != 0 && call_stack->frames + inline_depth < f)
|
||||
{
|
||||
f -= inline_depth;
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Halting All Attached Processes
|
||||
|
||||
@@ -3257,8 +3315,6 @@ ctrl_thread__entry_point(void *p)
|
||||
//- rjf: unpack per-message parameterizations & store
|
||||
{
|
||||
MemoryCopyArray(ctrl_state->exception_code_filters, msg->exception_code_filters);
|
||||
arena_clear(ctrl_state->user_meta_eval_arena);
|
||||
ctrl_state->user_meta_evals = *deep_copy_from_struct(ctrl_state->user_meta_eval_arena, CTRL_MetaEvalArray, &msg->meta_evals);
|
||||
}
|
||||
|
||||
//- rjf: process message
|
||||
@@ -4419,37 +4475,7 @@ ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
|
||||
//- rjf: meta evaluations
|
||||
case CTRL_EvalSpaceKind_Meta:
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U64 meta_eval_idx = space.u64s[0];
|
||||
if(meta_eval_idx < ctrl_state->user_meta_evals.count)
|
||||
{
|
||||
CTRL_MetaEval *meval = &ctrl_state->user_meta_evals.v[meta_eval_idx];
|
||||
|
||||
// rjf: copy meta evaluation to scratch arena, to form range of legal reads
|
||||
arena_push(scratch.arena, 0, 64);
|
||||
String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval);
|
||||
U64 pos_min = arena_pos(scratch.arena);
|
||||
CTRL_MetaEval *meval_read = struct_from_serialized(scratch.arena, CTRL_MetaEval, meval_srlzed);
|
||||
U64 pos_opl = arena_pos(scratch.arena);
|
||||
|
||||
// rjf: rebase all pointer values in meta evaluation to be relative to base pointer
|
||||
struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read);
|
||||
|
||||
// rjf: perform actual read
|
||||
Rng1U64 legal_range = r1u64(0, pos_opl-pos_min);
|
||||
if(contains_1u64(legal_range, range.min))
|
||||
{
|
||||
result = 1;
|
||||
U64 range_dim = dim_1u64(range);
|
||||
U64 bytes_to_read = Min(range_dim, (legal_range.max - range.min));
|
||||
MemoryCopy(out, ((U8 *)meval_read) + range.min, bytes_to_read);
|
||||
if(bytes_to_read < range_dim)
|
||||
{
|
||||
MemoryZero((U8 *)out + bytes_to_read, range_dim - bytes_to_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
|
||||
}break;
|
||||
}
|
||||
return result;
|
||||
@@ -5503,16 +5529,6 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
E_IRCtx *ctx = &ir_ctx;
|
||||
ctx->macro_map = push_array(temp.arena, E_String2ExprMap, 1);
|
||||
ctx->macro_map[0] = e_string2expr_map_make(temp.arena, 512);
|
||||
E_TypeKey meval_type_key = e_type_key_cons_base(type(CTRL_MetaEval));
|
||||
for EachIndex(idx, ctrl_state->user_meta_evals.count)
|
||||
{
|
||||
E_Space space = e_space_make(CTRL_EvalSpaceKind_Meta);
|
||||
E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0);
|
||||
expr->space = space;
|
||||
expr->mode = E_Mode_Offset;
|
||||
expr->type_key = meval_type_key;
|
||||
e_string2expr_map_insert(temp.arena, ctx->macro_map, ctrl_state->user_meta_evals.v[idx].label, expr);
|
||||
}
|
||||
}
|
||||
e_select_ir_ctx(&ir_ctx);
|
||||
|
||||
|
||||
+6
-240
@@ -12,229 +12,6 @@ typedef U64 CTRL_MachineID;
|
||||
|
||||
#define CTRL_MachineID_Local (1)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Meta Evaluation Types
|
||||
|
||||
//- rjf: auto-checkbox b32s
|
||||
|
||||
typedef struct CTRL_CheckB32 CTRL_CheckB32;
|
||||
struct CTRL_CheckB32
|
||||
{
|
||||
B32 b32;
|
||||
};
|
||||
|
||||
struct_members(CTRL_CheckB32)
|
||||
{
|
||||
member_lit_comp(CTRL_CheckB32, type(B32), b32),
|
||||
};
|
||||
struct_type(CTRL_CheckB32);
|
||||
|
||||
//- rjf: styled string types
|
||||
|
||||
ptr_type(CTRL_PlainString8__str_ptr_type, type(U8), .flags = TypeFlag_IsPlainText,.count_delimiter_name = str8_lit_comp("size"));
|
||||
ptr_type(CTRL_CodeString8__str_ptr_type, type(U8), .flags = TypeFlag_IsCodeText, .count_delimiter_name = str8_lit_comp("size"));
|
||||
ptr_type(CTRL_PathString8__str_ptr_type, type(U8), .flags = TypeFlag_IsPathText, .count_delimiter_name = str8_lit_comp("size"));
|
||||
Member CTRL_PlainString8__members[] =
|
||||
{
|
||||
member_lit_comp(String8, &CTRL_PlainString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")),
|
||||
member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")),
|
||||
};
|
||||
Member CTRL_CodeString8__members[] =
|
||||
{
|
||||
member_lit_comp(String8, &CTRL_CodeString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")),
|
||||
member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")),
|
||||
};
|
||||
Member CTRL_PathString8__members[] =
|
||||
{
|
||||
member_lit_comp(String8, &CTRL_PathString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")),
|
||||
member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")),
|
||||
};
|
||||
named_struct_type(CTRL_PlainString8, String8, .name = str8_lit_comp("string"));
|
||||
named_struct_type(CTRL_CodeString8, String8, .name = str8_lit_comp("string"));
|
||||
named_struct_type(CTRL_PathString8, String8, .name = str8_lit_comp("string"));
|
||||
|
||||
//- rjf: meta evaluation callstack types
|
||||
|
||||
typedef struct CTRL_MetaEvalFrame CTRL_MetaEvalFrame;
|
||||
struct CTRL_MetaEvalFrame
|
||||
{
|
||||
U64 vaddr;
|
||||
U64 inline_depth;
|
||||
};
|
||||
ptr_type(CTRL_MetaEvalFrame__vaddr_type, type(void), .flags = TypeFlag_IsExternal, .size = sizeof(U64));
|
||||
struct_members(CTRL_MetaEvalFrame)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEvalFrame, &CTRL_MetaEvalFrame__vaddr_type, vaddr),
|
||||
member_lit_comp(CTRL_MetaEvalFrame, type(U64), inline_depth),
|
||||
};
|
||||
struct_type(CTRL_MetaEvalFrame, .name = str8_lit_comp("callstack_frame"));
|
||||
typedef struct CTRL_MetaEvalFrameArray CTRL_MetaEvalFrameArray;
|
||||
struct CTRL_MetaEvalFrameArray
|
||||
{
|
||||
U64 count;
|
||||
CTRL_MetaEvalFrame *v;
|
||||
};
|
||||
ptr_type(CTRL_MetaEvalFrameArray__v_ptr_type, type(CTRL_MetaEvalFrame), .count_delimiter_name = str8_lit_comp("count"));
|
||||
struct_members(CTRL_MetaEvalFrameArray)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEvalFrameArray, type(U64), count, .pretty_name = str8_lit_comp("Frame Count")),
|
||||
{str8_lit_comp("v"), str8_lit_comp("Frame Addresses"), &CTRL_MetaEvalFrameArray__v_ptr_type, OffsetOf(CTRL_MetaEvalFrameArray, v)},
|
||||
};
|
||||
struct_type(CTRL_MetaEvalFrameArray, .name = str8_lit_comp("callstack_frames"));
|
||||
|
||||
//- rjf: meta evaluation instance types
|
||||
|
||||
typedef struct CTRL_MetaEval CTRL_MetaEval;
|
||||
struct CTRL_MetaEval
|
||||
{
|
||||
#define CTRL_MetaEval_MemberXList \
|
||||
X(B32, enabled, "Enabled")\
|
||||
X(B32, frozen, "Frozen")\
|
||||
X(U64, hit_count, "Hit Count")\
|
||||
X(U64, id, "ID")\
|
||||
X(Rng1U64, vaddr_range, "Address Range")\
|
||||
X(U32, color, "Color")\
|
||||
X(CTRL_CheckB32, debug_subprocesses,"Debug Subprocesses")\
|
||||
Y(String8, type(CTRL_CodeString8), label, "Label")\
|
||||
Y(String8, type(CTRL_PathString8), exe, "Executable Path")\
|
||||
Y(String8, type(CTRL_PathString8), dbg, "Debug Info Path")\
|
||||
Y(String8, type(CTRL_PlainString8), args, "Arguments")\
|
||||
Y(String8, type(CTRL_PathString8), working_directory, "Working Directory")\
|
||||
Y(String8, type(CTRL_CodeString8), entry_point, "Custom Entry Point")\
|
||||
Y(String8, type(CTRL_PathString8), stdout_path, "Standard Output Path")\
|
||||
Y(String8, type(CTRL_PathString8), stderr_path, "Standard Error Path")\
|
||||
Y(String8, type(CTRL_PathString8), stdin_path, "Standard Input Path")\
|
||||
Y(String8, type(CTRL_PathString8), source_location, "Source Location")\
|
||||
Y(String8, type(CTRL_CodeString8), function_location, "Function Location")\
|
||||
Y(String8, type(CTRL_CodeString8), address_location, "Address Location")\
|
||||
Y(String8, type(CTRL_PathString8), source_path, "Source Path")\
|
||||
Y(String8, type(CTRL_PathString8), destination_path, "Destination Path")\
|
||||
Y(String8, type(CTRL_CodeString8), type, "Type")\
|
||||
Y(String8, type(CTRL_CodeString8), view_rule, "View Rule")\
|
||||
Y(String8, type(CTRL_CodeString8), condition, "Condition")\
|
||||
X(CTRL_MetaEvalFrameArray, callstack, "Call Stack")
|
||||
#define X(T, name, pretty_name) T name;
|
||||
#define Y(T, ti, name, pretty_name) T name;
|
||||
CTRL_MetaEval_MemberXList
|
||||
#undef X
|
||||
#undef Y
|
||||
};
|
||||
struct_members(CTRL_MetaEval)
|
||||
{
|
||||
#define X(T, name, pretty_name_) member_lit_comp(CTRL_MetaEval, type(T), name, .pretty_name = str8_lit_comp(pretty_name_)),
|
||||
#define Y(T, ti, name, pretty_name_) member_lit_comp(CTRL_MetaEval, (ti), name, .pretty_name = str8_lit_comp(pretty_name_)),
|
||||
CTRL_MetaEval_MemberXList
|
||||
#undef X
|
||||
#undef Y
|
||||
};
|
||||
struct_type(CTRL_MetaEval);
|
||||
|
||||
//- rjf: filters on main meta evaluation bundle
|
||||
|
||||
struct_members(CTRL_BreakpointMetaEval)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEval, type(B32), enabled, .pretty_name = str8_lit_comp("Enabled")),
|
||||
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
|
||||
member_lit_comp(CTRL_MetaEval, type(U64), hit_count, .pretty_name = str8_lit_comp("Hit Count")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Label")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), condition, .pretty_name = str8_lit_comp("Condition")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_location, .pretty_name = str8_lit_comp("Source Location")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), function_location, .pretty_name = str8_lit_comp("Function Location")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), address_location, .pretty_name = str8_lit_comp("Address Location")),
|
||||
};
|
||||
|
||||
struct_members(CTRL_TargetMetaEval)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Label")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), exe, .pretty_name = str8_lit_comp("Executable")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PlainString8),args, .pretty_name = str8_lit_comp("Arguments")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), working_directory, .pretty_name = str8_lit_comp("Working Directory")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), entry_point, .pretty_name = str8_lit_comp("Custom Entry Point")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stdout_path, .pretty_name = str8_lit_comp("Standard Output Path")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stderr_path, .pretty_name = str8_lit_comp("Standard Error Path")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stdin_path, .pretty_name = str8_lit_comp("Standard Input Path")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CheckB32), debug_subprocesses, .pretty_name = str8_lit_comp("Debug Subprocesses")),
|
||||
};
|
||||
|
||||
struct_members(CTRL_PinMetaEval)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Expression")),
|
||||
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_location, .pretty_name = str8_lit_comp("Source Location")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), address_location, .pretty_name = str8_lit_comp("Address Location")),
|
||||
};
|
||||
|
||||
struct_members(CTRL_FilePathMapMetaEval)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_path, .pretty_name = str8_lit_comp("Source Path")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), destination_path, .pretty_name = str8_lit_comp("Destination Path")),
|
||||
};
|
||||
|
||||
struct_members(CTRL_AutoViewRuleMetaEval)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), type, .pretty_name = str8_lit_comp("Type")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), view_rule, .pretty_name = str8_lit_comp("View Rule")),
|
||||
};
|
||||
|
||||
struct_members(CTRL_MachineMetaEval)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")),
|
||||
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")),
|
||||
};
|
||||
|
||||
struct_members(CTRL_ProcessMetaEval)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")),
|
||||
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")),
|
||||
member_lit_comp(CTRL_MetaEval, type(U64), id, .pretty_name = str8_lit_comp("ID")),
|
||||
};
|
||||
|
||||
struct_members(CTRL_ModuleMetaEval)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), exe, .pretty_name = str8_lit_comp("Executable Path")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), dbg, .pretty_name = str8_lit_comp("Debug Info Path")),
|
||||
member_lit_comp(CTRL_MetaEval, type(Rng1U64), vaddr_range, .pretty_name = str8_lit_comp("Address Range")),
|
||||
};
|
||||
|
||||
struct_members(CTRL_ThreadMetaEval)
|
||||
{
|
||||
member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")),
|
||||
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")),
|
||||
member_lit_comp(CTRL_MetaEval, type(U64), id, .pretty_name = str8_lit_comp("ID")),
|
||||
member_lit_comp(CTRL_MetaEval, type(CTRL_MetaEvalFrameArray), callstack, .pretty_name = str8_lit_comp("Call Stack")),
|
||||
};
|
||||
|
||||
named_struct_type(CTRL_BreakpointMetaEval, CTRL_MetaEval, .name = str8_lit_comp("breakpoint"));
|
||||
named_struct_type(CTRL_TargetMetaEval, CTRL_MetaEval, .name = str8_lit_comp("target"));
|
||||
named_struct_type(CTRL_PinMetaEval, CTRL_MetaEval, .name = str8_lit_comp("pin"));
|
||||
named_struct_type(CTRL_FilePathMapMetaEval, CTRL_MetaEval, .name = str8_lit_comp("file_path_map"));
|
||||
named_struct_type(CTRL_AutoViewRuleMetaEval,CTRL_MetaEval, .name = str8_lit_comp("auto_view_rule"));
|
||||
named_struct_type(CTRL_MachineMetaEval, CTRL_MetaEval, .name = str8_lit_comp("machine"));
|
||||
named_struct_type(CTRL_ProcessMetaEval, CTRL_MetaEval, .name = str8_lit_comp("process"));
|
||||
named_struct_type(CTRL_ModuleMetaEval, CTRL_MetaEval, .name = str8_lit_comp("module"));
|
||||
named_struct_type(CTRL_ThreadMetaEval, CTRL_MetaEval, .name = str8_lit_comp("thread"));
|
||||
|
||||
//- rjf: meta evaluation array
|
||||
|
||||
typedef struct CTRL_MetaEvalArray CTRL_MetaEvalArray;
|
||||
struct CTRL_MetaEvalArray
|
||||
{
|
||||
CTRL_MetaEval *v;
|
||||
U64 count;
|
||||
};
|
||||
ptr_type(CTRL_MetaEvalArray__v_ptr_type, type(CTRL_BreakpointMetaEval), .count_delimiter_name = str8_lit_comp("count"));
|
||||
struct_members(CTRL_MetaEvalArray)
|
||||
{
|
||||
{str8_lit_comp("v"), {0}, &CTRL_MetaEvalArray__v_ptr_type, OffsetOf(CTRL_MetaEvalArray, v)},
|
||||
member_lit_comp(CTRL_MetaEvalArray, type(U64), count),
|
||||
};
|
||||
struct_type(CTRL_MetaEvalArray);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Handle Types
|
||||
|
||||
@@ -404,32 +181,23 @@ struct CTRL_Unwind
|
||||
////////////////////////////////
|
||||
//~ rjf: Call Stack Types
|
||||
|
||||
typedef struct CTRL_CallStackInlineFrame CTRL_CallStackInlineFrame;
|
||||
struct CTRL_CallStackInlineFrame
|
||||
{
|
||||
CTRL_CallStackInlineFrame *next;
|
||||
CTRL_CallStackInlineFrame *prev;
|
||||
RDI_InlineSite *inline_site;
|
||||
};
|
||||
|
||||
typedef struct CTRL_CallStackFrame CTRL_CallStackFrame;
|
||||
struct CTRL_CallStackFrame
|
||||
{
|
||||
CTRL_CallStackInlineFrame *first_inline_frame;
|
||||
CTRL_CallStackInlineFrame *last_inline_frame;
|
||||
U64 inline_frame_count;
|
||||
U64 parent_num;
|
||||
U64 unwind_count;
|
||||
U64 inline_depth;
|
||||
void *regs;
|
||||
RDI_Parsed *rdi;
|
||||
RDI_Procedure *procedure;
|
||||
RDI_InlineSite *inline_site;
|
||||
};
|
||||
|
||||
typedef struct CTRL_CallStack CTRL_CallStack;
|
||||
struct CTRL_CallStack
|
||||
{
|
||||
CTRL_CallStackFrame *frames;
|
||||
U64 concrete_frame_count;
|
||||
U64 inline_frame_count;
|
||||
U64 total_frame_count;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -573,7 +341,6 @@ struct CTRL_Msg
|
||||
String8 stdin_path;
|
||||
CTRL_TrapList traps;
|
||||
CTRL_UserBreakpointList user_bps;
|
||||
CTRL_MetaEvalArray meta_evals;
|
||||
};
|
||||
|
||||
typedef struct CTRL_MsgNode CTRL_MsgNode;
|
||||
@@ -909,8 +676,6 @@ struct CTRL_State
|
||||
DMN_EventNode *free_dmn_event_node;
|
||||
Arena *user_entry_point_arena;
|
||||
String8List user_entry_points;
|
||||
Arena *user_meta_eval_arena;
|
||||
CTRL_MetaEvalArray user_meta_evals;
|
||||
U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64];
|
||||
U64 process_counter;
|
||||
Arena *dbg_dir_arena;
|
||||
@@ -1121,6 +886,7 @@ internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *sto
|
||||
//~ rjf: Call Stack Building Functions
|
||||
|
||||
internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind);
|
||||
internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U64 unwind_count, U64 inline_depth);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Halting All Attached Processes
|
||||
|
||||
@@ -1631,7 +1631,7 @@ d_init(void)
|
||||
}
|
||||
|
||||
internal D_EventList
|
||||
d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64], CTRL_MetaEvalArray *meta_evals)
|
||||
d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64])
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
@@ -1972,7 +1972,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
||||
msg->debug_subprocesses = target->debug_subprocesses;
|
||||
msg->env_inherit = 1;
|
||||
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
|
||||
MemoryCopyStruct(&msg->meta_evals, meta_evals);
|
||||
str8_list_push(scratch.arena, &msg->entry_points, custom_entry_point_name);
|
||||
msg->env_string_list = env;
|
||||
}
|
||||
@@ -2005,7 +2004,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
||||
msg->exit_code = 1;
|
||||
msg->entity = process->handle;
|
||||
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
|
||||
MemoryCopyStruct(&msg->meta_evals, meta_evals);
|
||||
}
|
||||
}break;
|
||||
case D_CmdKind_KillAll:
|
||||
@@ -2014,7 +2012,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
||||
msg->kind = CTRL_MsgKind_KillAll;
|
||||
msg->exit_code = 1;
|
||||
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
|
||||
MemoryCopyStruct(&msg->meta_evals, meta_evals);
|
||||
}break;
|
||||
case D_CmdKind_Detach:
|
||||
{
|
||||
@@ -2029,7 +2026,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
||||
msg->kind = CTRL_MsgKind_Detach;
|
||||
msg->entity = process->handle;
|
||||
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
|
||||
MemoryCopyStruct(&msg->meta_evals, meta_evals);
|
||||
}
|
||||
}break;
|
||||
case D_CmdKind_Continue:
|
||||
@@ -2305,7 +2301,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
||||
msg->kind = CTRL_MsgKind_Attach;
|
||||
msg->entity_id = pid;
|
||||
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
|
||||
MemoryCopyStruct(&msg->meta_evals, meta_evals);
|
||||
}
|
||||
}break;
|
||||
}
|
||||
@@ -2327,7 +2322,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
||||
msg->entity = run_thread->handle;
|
||||
msg->parent = process->handle;
|
||||
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
|
||||
MemoryCopyStruct(&msg->meta_evals, meta_evals);
|
||||
MemoryCopyStruct(&msg->traps, &run_traps);
|
||||
D_BreakpointArray *bp_batches[] =
|
||||
{
|
||||
|
||||
@@ -495,6 +495,6 @@ internal B32 d_next_cmd(D_Cmd **cmd);
|
||||
//~ rjf: Main Layer Top-Level Calls
|
||||
|
||||
internal void d_init(void);
|
||||
internal D_EventList d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64], CTRL_MetaEvalArray *meta_evals);
|
||||
internal D_EventList d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]);
|
||||
|
||||
#endif // DBG_ENGINE_CORE_H
|
||||
|
||||
@@ -328,8 +328,11 @@ ASYNC_WORK_DEF(fs_stream_work)
|
||||
os_file_close(file);
|
||||
FileProperties post_props = os_properties_from_file_path(path);
|
||||
|
||||
//- rjf: abort if modification timestamps differ - we did not successfully read the file
|
||||
if(pre_props.modified != post_props.modified)
|
||||
//- rjf: abort if modification timestamps or sizes differ - we did not successfully read the file
|
||||
B32 read_good = (pre_props.modified == post_props.modified &&
|
||||
pre_props.size == post_props.size &&
|
||||
read_size == data.size);
|
||||
if(!read_good)
|
||||
{
|
||||
ProfScope("abort")
|
||||
{
|
||||
@@ -360,29 +363,14 @@ ASYNC_WORK_DEF(fs_stream_work)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(node != 0)
|
||||
if(node != 0 && read_good)
|
||||
{
|
||||
if(node->timestamp != 0)
|
||||
{
|
||||
ins_atomic_u64_inc_eval(&fs_shared->change_gen);
|
||||
}
|
||||
if(post_props.modified == pre_props.modified)
|
||||
{
|
||||
node->timestamp = post_props.modified;
|
||||
node->size = post_props.size;
|
||||
}
|
||||
U64 range_hash = fs_little_hash_from_string(str8_struct(&range));
|
||||
U64 range_slot_idx = range_hash%node->slots_count;
|
||||
FS_RangeSlot *range_slot = &node->slots[range_slot_idx];
|
||||
FS_RangeNode *range_node = 0;
|
||||
for(FS_RangeNode *n = range_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(MemoryMatchStruct(&n->range, &range))
|
||||
{
|
||||
range_node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
node->timestamp = post_props.modified;
|
||||
node->size = post_props.size;
|
||||
}
|
||||
}
|
||||
os_condition_variable_broadcast(path_stripe->cv);
|
||||
|
||||
+67
-239
@@ -2017,52 +2017,6 @@ rd_eval_blob_from_entity__cached(CTRL_Entity *entity)
|
||||
return result;
|
||||
}
|
||||
|
||||
//- rjf: entity -> meta eval
|
||||
|
||||
internal CTRL_MetaEval *
|
||||
rd_ctrl_meta_eval_from_ctrl_entity(Arena *arena, CTRL_Entity *entity)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
CTRL_MetaEval *meval = push_array(arena, CTRL_MetaEval, 1);
|
||||
meval->frozen = entity->is_frozen;
|
||||
meval->vaddr_range = entity->vaddr_range;
|
||||
meval->color = entity->rgba;
|
||||
meval->label = entity->string;
|
||||
meval->id = entity->id;
|
||||
if(entity->kind == CTRL_EntityKind_Thread)
|
||||
{
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process);
|
||||
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity);
|
||||
CTRL_CallStack rich_unwind = ctrl_call_stack_from_unwind(arena, di_scope, process, &base_unwind);
|
||||
meval->callstack.count = rich_unwind.total_frame_count;
|
||||
meval->callstack.v = push_array(arena, CTRL_MetaEvalFrame, meval->callstack.count);
|
||||
U64 idx = 0;
|
||||
for(U64 base_idx = 0; base_idx < rich_unwind.concrete_frame_count; base_idx += 1)
|
||||
{
|
||||
U64 inline_idx = 0;
|
||||
for(CTRL_CallStackInlineFrame *f = rich_unwind.frames[base_idx].first_inline_frame; f != 0; f = f->next, inline_idx += 1)
|
||||
{
|
||||
meval->callstack.v[idx].vaddr = regs_rip_from_arch_block(entity->arch, rich_unwind.frames[base_idx].regs);
|
||||
meval->callstack.v[idx].inline_depth = inline_idx + 1;
|
||||
idx += 1;
|
||||
}
|
||||
meval->callstack.v[idx].vaddr = regs_rip_from_arch_block(entity->arch, rich_unwind.frames[base_idx].regs);
|
||||
idx += 1;
|
||||
}
|
||||
di_scope_close(di_scope);
|
||||
}
|
||||
if(entity->kind == CTRL_EntityKind_Module)
|
||||
{
|
||||
DI_Key dbgi_key = ctrl_dbgi_key_from_module(entity);
|
||||
meval->label = str8_skip_last_slash(entity->string);
|
||||
meval->exe = path_normalized_from_string(arena, entity->string);
|
||||
meval->dbg = path_normalized_from_string(arena, dbgi_key.path);
|
||||
}
|
||||
ProfEnd();
|
||||
return meval;
|
||||
}
|
||||
|
||||
//- rjf: eval space reads/writes
|
||||
|
||||
internal B32
|
||||
@@ -2070,8 +2024,6 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
B32 result = 0;
|
||||
CTRL_MetaEval *meval_read = 0;
|
||||
Rng1U64 meval_legal_range = {0};
|
||||
switch(space.kind)
|
||||
{
|
||||
//- rjf: filesystem reads
|
||||
@@ -3954,49 +3906,37 @@ rd_window_frame(void)
|
||||
{
|
||||
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 rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind);
|
||||
if(rich_unwind.concrete_frame_count != 0)
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind);
|
||||
if(call_stack.count != 0)
|
||||
{
|
||||
ui_spacer(ui_em(1.5f, 1.f));
|
||||
}
|
||||
for(U64 idx = 0; idx < rich_unwind.concrete_frame_count; idx += 1)
|
||||
for(U64 idx = 0; idx < call_stack.count; idx += 1)
|
||||
{
|
||||
CTRL_CallStackFrame *f = &rich_unwind.frames[idx];
|
||||
CTRL_CallStackFrame *f = &call_stack.frames[idx];
|
||||
RDI_Parsed *rdi = f->rdi;
|
||||
RDI_Procedure *procedure = f->procedure;
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(arch, f->regs);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
|
||||
String8 module_name = module == &ctrl_entity_nil ? str8_lit("???") : str8_skip_last_slash(module->string);
|
||||
|
||||
// rjf: inline frames
|
||||
for(CTRL_CallStackInlineFrame *fin = f->last_inline_frame; fin != 0; fin = fin->prev)
|
||||
UI_PrefWidth(ui_children_sum(1)) UI_Row
|
||||
{
|
||||
String8 name = {0};
|
||||
name.str = rdi_string_from_idx(rdi, fin->inline_site->name_string_idx, &name.size);
|
||||
name.size = Min(512, name.size);
|
||||
UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(12.f, 1)) ui_labelf("0x%I64x", rip_vaddr);
|
||||
RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]"));
|
||||
if(name.size != 0)
|
||||
{
|
||||
RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1))
|
||||
{
|
||||
rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("[??? in %S]", module_name);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: concrete frame
|
||||
UI_PrefWidth(ui_children_sum(1)) UI_Row
|
||||
{
|
||||
String8 name = {0};
|
||||
name.str = rdi_name_from_procedure(rdi, procedure, &name.size);
|
||||
name.size = Min(512, name.size);
|
||||
if(f->inline_site != 0)
|
||||
{
|
||||
name.str = rdi_string_from_idx(rdi, f->inline_site->name_string_idx, &name.size);
|
||||
name.size = Min(512, name.size);
|
||||
}
|
||||
else if(f->procedure != 0)
|
||||
{
|
||||
name.str = rdi_name_from_procedure(rdi, procedure, &name.size);
|
||||
name.size = Min(512, name.size);
|
||||
}
|
||||
UI_TextAlignment(UI_TextAlign_Left) RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_em(12.f, 1)) ui_labelf("0x%I64x", rip_vaddr);
|
||||
if(f->parent_num != 0)
|
||||
{
|
||||
RD_Font(RD_FontSlot_Code) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) UI_PrefWidth(ui_text_dim(10, 1)) ui_label(str8_lit("[inlined]"));
|
||||
}
|
||||
if(name.size != 0)
|
||||
{
|
||||
RD_Font(RD_FontSlot_Code) UI_PrefWidth(ui_text_dim(10, 1))
|
||||
@@ -5070,56 +5010,6 @@ rd_window_frame(void)
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
|
||||
// rjf: copy call stack
|
||||
if(ctrl_entity->kind == CTRL_EntityKind_Thread)
|
||||
{
|
||||
if(ui_clicked(rd_icon_buttonf(RD_IconKind_Clipboard, 0, "Copy Call Stack")))
|
||||
{
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
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 rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind);
|
||||
String8List lines = {0};
|
||||
for(U64 frame_idx = 0; frame_idx < rich_unwind.concrete_frame_count; frame_idx += 1)
|
||||
{
|
||||
CTRL_CallStackFrame *concrete_frame = &rich_unwind.frames[frame_idx];
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(ctrl_entity->arch, concrete_frame->regs);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
|
||||
RDI_Parsed *rdi = concrete_frame->rdi;
|
||||
RDI_Procedure *procedure = concrete_frame->procedure;
|
||||
for(CTRL_CallStackInlineFrame *inline_frame = concrete_frame->last_inline_frame;
|
||||
inline_frame != 0;
|
||||
inline_frame = inline_frame->prev)
|
||||
{
|
||||
RDI_InlineSite *inline_site = inline_frame->inline_site;
|
||||
String8 name = {0};
|
||||
name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size);
|
||||
str8_list_pushf(scratch.arena, &lines, "0x%I64x: [inlined] \"%S\"%s%S", rip_vaddr, name, module == &ctrl_entity_nil ? "" : " in ", module->string);
|
||||
}
|
||||
if(procedure != 0)
|
||||
{
|
||||
String8 name = {0};
|
||||
name.str = rdi_name_from_procedure(rdi, procedure, &name.size);
|
||||
str8_list_pushf(scratch.arena, &lines, "0x%I64x: \"%S\"%s%S", rip_vaddr, name, module == &ctrl_entity_nil ? "" : " in ", module->string);
|
||||
}
|
||||
else if(module != &ctrl_entity_nil)
|
||||
{
|
||||
str8_list_pushf(scratch.arena, &lines, "0x%I64x: [??? in %S]", rip_vaddr, module->string);
|
||||
}
|
||||
else
|
||||
{
|
||||
str8_list_pushf(scratch.arena, &lines, "0x%I64x: [??? in ???]", rip_vaddr);
|
||||
}
|
||||
}
|
||||
StringJoin join = {0};
|
||||
join.sep = join.post = str8_lit("\n");
|
||||
String8 text = str8_list_join(scratch.arena, &lines, &join);
|
||||
os_set_clipboard_text(text);
|
||||
ui_ctx_menu_close();
|
||||
di_scope_close(di_scope);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: find
|
||||
if(ctrl_entity->kind == CTRL_EntityKind_Thread)
|
||||
{
|
||||
@@ -9101,6 +8991,7 @@ typedef struct RD_CallStackLookupAccel RD_CallStackLookupAccel;
|
||||
struct RD_CallStackLookupAccel
|
||||
{
|
||||
Arch arch;
|
||||
CTRL_Handle process;
|
||||
CTRL_CallStack call_stack;
|
||||
};
|
||||
|
||||
@@ -9122,8 +9013,9 @@ E_LOOKUP_INFO_FUNCTION_DEF(call_stack)
|
||||
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, rd_state->frame_di_scope, process, &base_unwind);
|
||||
result.idxed_expr_count = accel->call_stack.total_frame_count;
|
||||
result.idxed_expr_count = accel->call_stack.count;
|
||||
}
|
||||
result.user_data = accel;
|
||||
}
|
||||
@@ -9144,23 +9036,13 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(call_stack)
|
||||
E_Value rhs_value = rhs_interp.value;
|
||||
RD_CallStackLookupAccel *accel = (RD_CallStackLookupAccel *)user_data;
|
||||
CTRL_CallStack *call_stack = &accel->call_stack;
|
||||
if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->total_frame_count)
|
||||
if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->count)
|
||||
{
|
||||
U64 frame_idx = 0;
|
||||
#if 0
|
||||
for(U64 base_idx = 0; base_idx < call_stack->concrete_frame_count; base_idx += 1, frame_idx += 1)
|
||||
{
|
||||
CTRL_CallStackFrame *base_frame = call_stack->frames + base_idx;
|
||||
for(CTRL_CallStackInlineFrame *inline_frame = base_frame->first_inline_frame; inline_frame != 0; inline_frame = inline_frame->next, frame_idx += 1)
|
||||
{
|
||||
if(frame_idx == rhs_value.u64)
|
||||
{
|
||||
result.irtree_and_type.root = e_irtree_const_u(arena, );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, accel->process);
|
||||
CTRL_CallStackFrame *f = &call_stack->frames[rhs_value.u64];
|
||||
result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, RD_EvalSpaceKind_CtrlEntity), e_irtree_const_u(arena, regs_rip_from_arch_block(accel->arch, f->regs)));
|
||||
result.irtree_and_type.type_key = e_type_key_cons_ptr(process->arch, e_type_key_basic(E_TypeKind_Void), 1, 0);
|
||||
result.irtree_and_type.mode = E_Mode_Value;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
@@ -9234,30 +9116,20 @@ E_LOOKUP_INFO_FUNCTION_DEF(environment)
|
||||
return result;
|
||||
}
|
||||
|
||||
E_LOOKUP_ACCESS_FUNCTION_DEF(environment)
|
||||
E_LOOKUP_RANGE_FUNCTION_DEF(environment)
|
||||
{
|
||||
E_LookupAccess result = {{&e_irnode_nil}};
|
||||
if(kind == E_ExprKind_ArrayIndex)
|
||||
RD_CfgArray *cfgs = (RD_CfgArray *)user_data;
|
||||
Rng1U64 legal_idx_range = r1u64(0, cfgs->count);
|
||||
Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range);
|
||||
U64 read_range_count = dim_1u64(read_range);
|
||||
for(U64 idx = 0; idx < read_range_count; idx += 1)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
RD_CfgArray *accel = (RD_CfgArray *)user_data;
|
||||
E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs);
|
||||
E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root);
|
||||
String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist);
|
||||
E_Interpretation rhs_interp = e_interpret(rhs_bytecode);
|
||||
E_Value rhs_value = rhs_interp.value;
|
||||
U64 rhs_index = rhs_value.u64;
|
||||
if(contains_1u64(r1u64(0, accel->count), rhs_index))
|
||||
U64 cfg_idx = read_range.min + idx;
|
||||
if(cfg_idx < cfgs->count)
|
||||
{
|
||||
RD_Cfg *env_string = accel->v[rhs_index];
|
||||
E_TypeKey type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText);
|
||||
result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(env_string), e_irtree_const_u(arena, 0));
|
||||
result.irtree_and_type.type_key = type_key;
|
||||
result.irtree_and_type.mode = E_Mode_Offset;
|
||||
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment)
|
||||
@@ -12351,8 +12223,6 @@ rd_frame(void)
|
||||
}
|
||||
B32 allow_text_hotkeys = !rd_state->text_edit_mode;
|
||||
rd_state->text_edit_mode = 0;
|
||||
rd_state->ctrl_entity_meval_cache_slots_count = 1024;
|
||||
rd_state->ctrl_entity_meval_cache_slots = push_array(rd_frame_arena(), RD_CtrlEntityMetaEvalCacheSlot, rd_state->ctrl_entity_meval_cache_slots_count);
|
||||
rd_state->cfg2evalblob_map = push_array(rd_frame_arena(), RD_Cfg2EvalBlobMap, 1);
|
||||
rd_state->cfg2evalblob_map->slots_count = 256;
|
||||
rd_state->cfg2evalblob_map->slots = push_array(rd_frame_arena(), RD_Cfg2EvalBlobSlot, rd_state->cfg2evalblob_map->slots_count);
|
||||
@@ -13080,7 +12950,6 @@ rd_frame(void)
|
||||
////////////////////////////
|
||||
//- rjf: build eval IR context
|
||||
//
|
||||
E_TypeKey meta_eval_type_key = e_type_key_cons_base(type(CTRL_MetaEval));
|
||||
E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1);
|
||||
if(e_ir_state != 0) { e_ir_state->ctx = 0; }
|
||||
{
|
||||
@@ -13327,7 +13196,7 @@ rd_frame(void)
|
||||
{
|
||||
e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("environment"),
|
||||
.info = E_LOOKUP_INFO_FUNCTION_NAME(environment),
|
||||
.access = E_LOOKUP_ACCESS_FUNCTION_NAME(environment),
|
||||
.range = E_LOOKUP_RANGE_FUNCTION_NAME(environment),
|
||||
.id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(environment),
|
||||
.num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(environment));
|
||||
e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("call_stack"),
|
||||
@@ -16074,19 +15943,16 @@ Z(getting_started)
|
||||
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, 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 rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind);
|
||||
if(rd_regs()->unwind_count < rich_unwind.concrete_frame_count)
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind);
|
||||
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)
|
||||
{
|
||||
frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, 0);
|
||||
}
|
||||
if(frame)
|
||||
{
|
||||
CTRL_CallStackFrame *frame = &rich_unwind.frames[rd_regs()->unwind_count];
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, frame->regs);
|
||||
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
|
||||
rd_state->base_regs.v.module = module->handle;
|
||||
rd_state->base_regs.v.unwind_count = rd_regs()->unwind_count;
|
||||
rd_state->base_regs.v.inline_depth = 0;
|
||||
if(rd_regs()->inline_depth <= frame->inline_frame_count)
|
||||
{
|
||||
rd_state->base_regs.v.inline_depth = rd_regs()->inline_depth;
|
||||
}
|
||||
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);
|
||||
di_scope_close(di_scope);
|
||||
@@ -16098,46 +15964,30 @@ Z(getting_started)
|
||||
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, 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 rich_unwind = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind);
|
||||
U64 crnt_unwind_idx = rd_state->base_regs.v.unwind_count;
|
||||
U64 crnt_inline_dpt = rd_state->base_regs.v.inline_depth;
|
||||
U64 next_unwind_idx = crnt_unwind_idx;
|
||||
U64 next_inline_dpt = crnt_inline_dpt;
|
||||
if(crnt_unwind_idx < rich_unwind.concrete_frame_count)
|
||||
CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, process, &base_unwind);
|
||||
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)
|
||||
{
|
||||
CTRL_CallStackFrame *f = &rich_unwind.frames[crnt_unwind_idx];
|
||||
switch(kind)
|
||||
default:{}break;
|
||||
case RD_CmdKind_UpOneFrame:
|
||||
if(current_frame > call_stack.frames)
|
||||
{
|
||||
default:{}break;
|
||||
case RD_CmdKind_UpOneFrame:
|
||||
{
|
||||
if(crnt_inline_dpt < f->inline_frame_count)
|
||||
{
|
||||
next_inline_dpt += 1;
|
||||
}
|
||||
else if(crnt_unwind_idx > 0)
|
||||
{
|
||||
next_unwind_idx -= 1;
|
||||
next_inline_dpt = 0;
|
||||
}
|
||||
}break;
|
||||
case RD_CmdKind_DownOneFrame:
|
||||
{
|
||||
if(crnt_inline_dpt > 0)
|
||||
{
|
||||
next_inline_dpt -= 1;
|
||||
}
|
||||
else if(crnt_unwind_idx < rich_unwind.concrete_frame_count)
|
||||
{
|
||||
next_unwind_idx += 1;
|
||||
next_inline_dpt = (f+1)->inline_frame_count;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
next_frame = current_frame-1;
|
||||
}break;
|
||||
case RD_CmdKind_DownOneFrame:
|
||||
if(current_frame+1 < call_stack.frames + call_stack.count)
|
||||
{
|
||||
next_frame = current_frame+1;
|
||||
}break;
|
||||
}
|
||||
if(next_frame != 0)
|
||||
{
|
||||
CTRL_CallStackFrame *next_base_frame = next_frame + next_frame->inline_depth;
|
||||
rd_cmd(RD_CmdKind_SelectUnwind,
|
||||
.unwind_count = next_frame->unwind_count,
|
||||
.inline_depth = next_frame->inline_depth);
|
||||
}
|
||||
rd_cmd(RD_CmdKind_SelectUnwind,
|
||||
.unwind_count = next_unwind_idx,
|
||||
.inline_depth = next_inline_dpt);
|
||||
di_scope_close(di_scope);
|
||||
}break;
|
||||
|
||||
@@ -16628,18 +16478,8 @@ Z(getting_started)
|
||||
//- rjf: gather breakpoints & meta-evals (for the engine, meta-evals can only be referenced by breakpoints)
|
||||
//
|
||||
D_BreakpointArray breakpoints = {0};
|
||||
CTRL_MetaEvalArray meta_evals = {0};
|
||||
ProfScope("gather breakpoints & meta-evals")
|
||||
{
|
||||
typedef struct MetaEvalNode MetaEvalNode;
|
||||
struct MetaEvalNode
|
||||
{
|
||||
MetaEvalNode *next;
|
||||
CTRL_MetaEval *meval;
|
||||
};
|
||||
U64 meval_count = 0;
|
||||
MetaEvalNode *first_meval = 0;
|
||||
MetaEvalNode *last_meval = 0;
|
||||
RD_CfgList bp_cfgs = rd_cfg_top_level_list_from_string(scratch.arena, str8_lit("breakpoint"));
|
||||
breakpoints.count = bp_cfgs.count;
|
||||
breakpoints.v = push_array(scratch.arena, D_Breakpoint, breakpoints.count);
|
||||
@@ -16737,18 +16577,6 @@ Z(getting_started)
|
||||
dst_bp->condition = src_bp_cnd;
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
//- rjf: meta-eval list -> array
|
||||
meta_evals.count = meval_count;
|
||||
meta_evals.v = push_array(scratch.arena, CTRL_MetaEval, meta_evals.count);
|
||||
{
|
||||
U64 idx = 0;
|
||||
for(MetaEvalNode *n = first_meval; n != 0; n = n->next)
|
||||
{
|
||||
MemoryCopyStruct(&meta_evals.v[idx], n->meval);
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
@@ -16823,7 +16651,7 @@ Z(getting_started)
|
||||
//- rjf: tick debug engine
|
||||
//
|
||||
U64 cmd_count_pre_tick = rd_state->cmds[0].count;
|
||||
D_EventList engine_events = d_tick(scratch.arena, &targets, &breakpoints, &path_maps, exception_code_filters, &meta_evals);
|
||||
D_EventList engine_events = d_tick(scratch.arena, &targets, &breakpoints, &path_maps, exception_code_filters);
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: process debug engine events
|
||||
|
||||
@@ -617,25 +617,6 @@ struct RD_WindowStateSlot
|
||||
RD_WindowState *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Meta Evaluation Cache Types
|
||||
|
||||
typedef struct RD_CtrlEntityMetaEvalCacheNode RD_CtrlEntityMetaEvalCacheNode;
|
||||
struct RD_CtrlEntityMetaEvalCacheNode
|
||||
{
|
||||
RD_CtrlEntityMetaEvalCacheNode *next;
|
||||
CTRL_Handle handle;
|
||||
CTRL_MetaEval *meval;
|
||||
Rng1U64 range;
|
||||
};
|
||||
|
||||
typedef struct RD_CtrlEntityMetaEvalCacheSlot RD_CtrlEntityMetaEvalCacheSlot;
|
||||
struct RD_CtrlEntityMetaEvalCacheSlot
|
||||
{
|
||||
RD_CtrlEntityMetaEvalCacheNode *first;
|
||||
RD_CtrlEntityMetaEvalCacheNode *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Config -> Eval Blob Cache Types
|
||||
|
||||
@@ -788,10 +769,6 @@ struct RD_State
|
||||
Arena *string_search_arena;
|
||||
String8 string_search_string;
|
||||
|
||||
// rjf: ctrl entity meta eval cache
|
||||
U64 ctrl_entity_meval_cache_slots_count;
|
||||
RD_CtrlEntityMetaEvalCacheSlot *ctrl_entity_meval_cache_slots;
|
||||
|
||||
// rjf: contextual hover info
|
||||
RD_Regs *hover_regs;
|
||||
RD_RegSlot hover_regs_slot;
|
||||
@@ -1055,9 +1032,6 @@ internal String8 rd_eval_blob_from_cfg__cached(RD_Cfg *cfg);
|
||||
internal String8 rd_eval_blob_from_entity(Arena *arena, CTRL_Entity *entity);
|
||||
internal String8 rd_eval_blob_from_entity__cached(CTRL_Entity *entity);
|
||||
|
||||
//- rjf: entity -> meta eval
|
||||
internal CTRL_MetaEval *rd_ctrl_meta_eval_from_ctrl_entity(Arena *arena, CTRL_Entity *entity);
|
||||
|
||||
//- rjf: eval space reads/writes
|
||||
internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range);
|
||||
internal B32 rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range);
|
||||
|
||||
Reference in New Issue
Block a user