From 4278f7db1ee12b889bdf5660309cabec3a5a09ea Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 13 Nov 2024 11:47:17 -0800 Subject: [PATCH] extend pre-emptive conversion rule to do limited children directory checking as well --- src/ctrl/ctrl_core.c | 74 +++++++++++++++++++++++++-------------- src/raddbg/raddbg_core.c | 31 ++++++---------- src/raddbg/raddbg_views.c | 4 +-- 3 files changed, 61 insertions(+), 48 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 789bead4..a66f640e 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4111,16 +4111,18 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, } ctrl_c2u_push_events(&evts); - //- rjf: when a new process is loaded, for the first module, pre-emptively try - // to open all adjacent debug infos. with debug events, we learn about loaded - // modules serially, and we need to completely load debug info before continuing. - // for massive projects, this is a problem, because completely loading debug info - // isn't a trivial cost, and there are often 100s of DLLs. + //- rjf: when a new process is loaded, for the first module, pre-emptively + // try to open all adjacent debug infos. with debug events, we learn about + // loaded modules serially, and we need to completely load debug info before + // continuing. for massive projects, this is a problem, because completely + // loading debug info isn't a trivial cost, and there are often 1000s of + // DLLs. + // + // an imperfect but usually reasonable heuristic is to look at adjacent + // debug info files, in the same or under the directory as the initially + // loaded, and pre-emptively convert all of them (which for us is the + // heaviest part of debug info loading, if native RDI is not used). // - // an imperfect but usually reasonable heuristic is to look at adjacent debug info - // files, in the same directory as the initially loaded, and pre-emptively convert - // all of them (which for us is the heaviest part of debug info loading, if native - // RDI is not used). if(event->kind == DMN_EventKind_LoadModule) { CTRL_Handle process_handle = ctrl_handle_make(CTRL_MachineID_Local, event->process); @@ -4136,7 +4138,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, break; } } - if(is_first) + if(is_first) ProfScope("pre-emptively load adjacent debug info") { DI_Key loaded_di_key = ctrl_dbgi_key_from_module(loaded_module); String8 loaded_di_name = str8_skip_last_slash(loaded_di_key.path); @@ -4144,26 +4146,46 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, if(containing_folder_path.size < loaded_di_key.path.size) { String8 debug_info_ext = str8_skip_last_dot(loaded_di_key.path); - OS_FileIter *it = os_file_iter_begin(scratch.arena, containing_folder_path, OS_FileIterFlag_SkipFolders); - DI_KeyList preemptively_loaded_keys = {0}; - for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) + typedef struct Task Task; + struct Task { - if(str8_match(str8_skip_last_dot(info.name), debug_info_ext, StringMatchFlag_CaseInsensitive) && - !str8_match(loaded_di_name, info.name, StringMatchFlag_CaseInsensitive)) + Task *next; + String8 path; + }; + Task start_task = {0, containing_folder_path}; + Task *first_task = &start_task; + Task *last_task = first_task; + U64 task_count = 0; + for(Task *t = first_task; t != 0; t = t->next) + { + OS_FileIter *it = os_file_iter_begin(scratch.arena, t->path, 0); + DI_KeyList preemptively_loaded_keys = {0}; + for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, it, &info);) { - DI_Key key = {push_str8f(scratch.arena, "%S/%S", containing_folder_path, info.name), info.props.modified}; - di_open(&key); - di_key_list_push(scratch.arena, &preemptively_loaded_keys, &key); + if(info.props.flags & FilePropertyFlag_IsFolder && task_count < 16384) + { + Task *task = push_array(scratch.arena, Task, 1); + task->path = push_str8f(scratch.arena, "%S/%S", t->path, info.name); + SLLQueuePush(first_task, last_task, task); + task_count += 1; + } + else if(str8_match(str8_skip_last_dot(info.name), debug_info_ext, StringMatchFlag_CaseInsensitive) && + !str8_match(loaded_di_name, info.name, StringMatchFlag_CaseInsensitive)) + { + DI_Key key = {push_str8f(scratch.arena, "%S/%S", t->path, info.name), info.props.modified}; + di_open(&key); + di_key_list_push(scratch.arena, &preemptively_loaded_keys, &key); + } } + for(DI_KeyNode *n = preemptively_loaded_keys.first; n != 0; n = n->next) + { + DI_Scope *di_scope = di_scope_open(); + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &n->v, max_U64); + di_scope_close(di_scope); + di_close(&n->v); + } + os_file_iter_end(it); } - for(DI_KeyNode *n = preemptively_loaded_keys.first; n != 0; n = n->next) - { - DI_Scope *di_scope = di_scope_open(); - RDI_Parsed *rdi = di_rdi_from_key(di_scope, &n->v, max_U64); - di_scope_close(di_scope); - di_close(&n->v); - } - os_file_iter_end(it); } } } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 5b3d57e5..c2c2255c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -11704,6 +11704,7 @@ rd_init(CmdLine *cmdln) internal void rd_frame(void) { + ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); local_persist S32 depth = 0; log_scope_begin(); @@ -11843,6 +11844,7 @@ rd_frame(void) ////////////////////////////// //- rjf: consume events // + ProfScope("consume events") { for(OS_Event *event = events.first, *next = 0; event != 0; @@ -11973,11 +11975,12 @@ rd_frame(void) // CTRL_Handle find_thread_retry = {0}; RD_Cmd *cmd = 0; - for(U64 cmd_process_loop_idx = 0; cmd_process_loop_idx < 3; cmd_process_loop_idx += 1) + ProfScope("loop - consume events in core, tick engine, and repeat") for(U64 cmd_process_loop_idx = 0; cmd_process_loop_idx < 3; cmd_process_loop_idx += 1) { //////////////////////////// //- rjf: unpack eval-dependent info // + ProfBegin("unpack eval-dependent info"); CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); Arch arch = thread->arch; @@ -11994,6 +11997,7 @@ rd_frame(void) eval_modules_primary->rdi = &di_rdi_parsed_nil; eval_modules_primary->vaddr_range = r1u64(0, max_U64); DI_Key primary_dbgi_key = {0}; + ProfScope("produce all eval modules") { U64 eval_module_idx = 0; for(CTRL_EntityNode *n = all_modules.first; n != 0; n = n->next, eval_module_idx += 1) @@ -12010,30 +12014,13 @@ rd_frame(void) } } } - U64 rdis_count = Max(1, all_modules.count); - RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); - rdis[0] = &di_rdi_parsed_nil; - U64 rdis_primary_idx = 0; - Rng1U64 *rdis_vaddr_ranges = push_array(scratch.arena, Rng1U64, rdis_count); - { - U64 idx = 0; - for(CTRL_EntityNode *n = all_modules.first; n != 0; n = n->next, idx += 1) - { - DI_Key dbgi_key = ctrl_dbgi_key_from_module(n->v); - rdis[idx] = di_rdi_from_key(rd_state->frame_di_scope, &dbgi_key, 0); - rdis_vaddr_ranges[idx] = n->v->vaddr_range; - if(n->v == module) - { - primary_dbgi_key = dbgi_key; - rdis_primary_idx = idx; - } - } - } + ProfEnd(); //////////////////////////// //- rjf: build eval type context // E_TypeCtx *type_ctx = push_array(scratch.arena, E_TypeCtx, 1); + ProfScope("build eval type context") { E_TypeCtx *ctx = type_ctx; ctx->ip_vaddr = rip_vaddr; @@ -16662,6 +16649,7 @@ rd_frame(void) ////////////////////////////// //- rjf: compute all ambiguous paths from view titles // + ProfScope("compute all ambiguous paths from view titles") { Temp scratch = scratch_begin(0, 0); rd_state->ambiguous_path_slots_count = 512; @@ -16776,6 +16764,7 @@ rd_frame(void) ////////////////////////////// //- rjf: submit rendering to all windows // + ProfScope("submit rendering to all windows") { r_begin_frame(); for(RD_Window *w = rd_state->first_window; w != 0; w = w->next) @@ -16859,6 +16848,7 @@ rd_frame(void) ////////////////////////////// //- rjf: collect logs // + ProfScope("collect logs") { LogScopeResult log = log_scope_end(scratch.arena); os_append_data_to_file_path(rd_state->log_path, log.strings[LogMsgKind_Info]); @@ -16874,4 +16864,5 @@ rd_frame(void) } scratch_end(scratch); + ProfEnd(); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index f2b38a76..83d2e88f 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -5343,10 +5343,10 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) { RD_Font(RD_FontSlot_Code) rd_code_label(1.f, 0, rd_rgba_from_theme_color(RD_ThemeColor_CodeSymbol), name); RD_Font(RD_FontSlot_Main) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) - ui_labelf("Procedure #%I64u", item->idx); + ui_labelf("Procedure #%I64u", idx); U64 binary_voff = d_voff_from_dbgi_key_symbol_name(&dbgi_key, name); D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, binary_voff); - if(lines.first != 0) + if(lines.first != 0 && lines.first->v.file_path.size != 0 && lines.first->v.pt.line != 0) { String8 file_path = lines.first->v.file_path; S64 line_num = lines.first->v.pt.line;