diff --git a/project.4coder b/project.4coder index dae43a1f..e793b63f 100644 --- a/project.4coder +++ b/project.4coder @@ -49,7 +49,7 @@ commands = // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [raddbg wsl] // .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/project.raddbg b/project.raddbg index 74ff8bda..4019e3e2 100644 --- a/project.raddbg +++ b/project.raddbg @@ -6,6 +6,7 @@ target: executable: "build/raddbg.exe" working_directory: build arguments: "--user:raddbg_test.user --project:raddbg_test.project" + enabled: 1 } target: { @@ -26,14 +27,13 @@ target: } target: { - executable: "build/raddbg.exe" - working_directory: "build/dwarf" - arguments: "--bin --rdi a.exe" + executable: "build/radbin.exe" + working_directory: build + arguments: "--rdi chrome.dll.pdb --capture" } target: { executable: "build/radbin.exe" - working_directory: "build/" - enabled: 1 - arguments: "--rdi chrome.dll.pdb" + working_directory: build + arguments: "--rdi raddbg.pdb" } diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index 61e65300..1114816d 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -104,6 +104,7 @@ D_EntityKindTable: {Thread thread "Thread" } {Module module "Module" } {EntryPoint entry_point "Entry Point" } + {LaunchMsgID launch_msg_id "Launch Message ID" } {DebugInfoPath debug_info_path "Debug Info Path" } {PendingThreadName pending_thread_name "Pending Thread Name" } {PendingThreadColor pending_thread_color "Pending Thread Color" } diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 652379e8..dbf192bb 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -86,8 +86,7 @@ d_init(void) d_user_state = push_array(arena, D_UserState, 1); d_user_state->arena = arena; d_user_state->cmds_arena = arena_alloc(); - d_user_state->output_log_key = c_key_make(c_root_alloc(), c_id_make(0, 0)); - c_submit_data(d_user_state->output_log_key, 0, str8_zero()); + d_user_state->output_log_root = c_root_alloc(); d_user_state->ctrl_entity_store = d_entity_ctx_rw_store_alloc(); d_user_state->ctrl_stop_arena = arena_alloc(); d_user_state->ctrl_msg_arena = arena_alloc(); diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 74c991da..d9676383 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -140,6 +140,7 @@ struct D_Entity U64 tls_index; U64 tls_offset; OperatingSystem target_os; + D_MsgID src_msg_id; }; typedef struct D_EntityNode D_EntityNode; @@ -248,6 +249,7 @@ struct D_Target String8 stdout_path; String8 stderr_path; String8 stdin_path; + D_MsgID msg_id; B32 debug_subprocesses; String8List env; }; diff --git a/src/dbg_engine/dbg_engine_ctrl.c b/src/dbg_engine/dbg_engine_ctrl.c index 7314c462..12cdba0b 100644 --- a/src/dbg_engine/dbg_engine_ctrl.c +++ b/src/dbg_engine/dbg_engine_ctrl.c @@ -1302,6 +1302,7 @@ d_entity_store_apply_events(D_EntityCtxRWStore *store, D_EventList *list) D_Entity *process = d_entity_alloc(store, machine, D_EntityKind_Process, event->arch, event->entity, (U64)event->entity_id); process->tls_model = event->tls_model; process->target_os = event->target_os; + process->src_msg_id = event->msg_id; d_entity_equip_string(store, process, event->string); } }break; @@ -1314,7 +1315,8 @@ d_entity_store_apply_events(D_EntityCtxRWStore *store, D_EventList *list) entry = next) { next = entry->next; - if(entry->kind == D_EntityKind_EntryPoint && entry->id == process->id) + if(entry->id == process->id && + (entry->kind == D_EntityKind_EntryPoint || entry->kind == D_EntityKind_LaunchMsgID)) { d_entity_release(store, entry); } @@ -4536,9 +4538,21 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D default:{}break; case DMN_EventKind_CreateProcess: { + D_MsgID msg_id = 0; + for(D_Entity *entry = d_ctrl_state->ctrl_thread_entity_store->ctx.root->first; + entry != &d_entity_nil; + entry = entry->next) + { + if(entry->id == event->code && entry->kind == D_EntityKind_LaunchMsgID) + { + msg_id = entry->src_msg_id; + d_entity_release(d_ctrl_state->ctrl_thread_entity_store, entry); + break; + } + } D_Event *out_evt = d_event_list_push(scratch.arena, &evts); out_evt->kind = D_EventKind_NewProc; - out_evt->msg_id = msg->msg_id; + out_evt->msg_id = msg_id; out_evt->entity = d_handle_from_dmn(D_MachineID_Local, event->process); out_evt->arch = event->arch; out_evt->entity_id = event->code; @@ -5081,15 +5095,21 @@ d_ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg) file_close(stderr_handle); file_close(stdin_handle); - //- rjf: record (id -> entry points), so that we know custom entry points for this PID + //- rjf: record (id -> entry points), and (id -> msg_id) so that we know custom entry points for this PID D_EntityCtxRWStore *entity_ctx_rw_store = d_ctrl_state->ctrl_thread_entity_store; MutexScopeW(d_ctrl_state->ctrl_thread_entity_ctx_rw_mutex) { for(String8Node *n = msg->entry_points.first; n != 0; n = n->next) { - String8 string = n->string; - D_Entity *entry = d_entity_alloc(entity_ctx_rw_store, entity_ctx_rw_store->ctx.root, D_EntityKind_EntryPoint, Arch_Null, d_handle_zero(), (U64)id); - d_entity_equip_string(entity_ctx_rw_store, entry, string); + { + String8 string = n->string; + D_Entity *entry = d_entity_alloc(entity_ctx_rw_store, entity_ctx_rw_store->ctx.root, D_EntityKind_EntryPoint, Arch_Null, d_handle_zero(), (U64)id); + d_entity_equip_string(entity_ctx_rw_store, entry, string); + } + { + D_Entity *entry = d_entity_alloc(entity_ctx_rw_store, entity_ctx_rw_store->ctx.root, D_EntityKind_LaunchMsgID, Arch_Null, d_handle_zero(), (U64)id); + entry->src_msg_id = msg->msg_id; + } } } diff --git a/src/dbg_engine/dbg_engine_user.c b/src/dbg_engine/dbg_engine_user.c index ae1f5d13..c520e007 100644 --- a/src/dbg_engine/dbg_engine_user.c +++ b/src/dbg_engine/dbg_engine_user.c @@ -377,7 +377,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread) rng1u64_list_push(scratch.arena, &all_vaddr_ranges_on_same_line, vaddr_range); } } - + // extend trap-net range across contiguous same-source-line, possibly unsorted, ranges // // TODO: @ns: converter should never produce these ranges in the first place, @@ -1628,23 +1628,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P d_user_state->ctrl_last_stop_event.string = push_str8_copy(d_user_state->ctrl_stop_arena, d_user_state->ctrl_last_stop_event.string); } }break; - - case D_EventKind_NewProc: - { - // rjf: the first process? -> clear session output - D_EntityArray existing_processes = d_entity_array_from_kind(D_EntityKind_Process); - if(existing_processes.count == 1) - { - MTX_Op op = {r1u64(0, 0xffffffffffffffffull), str8_lit("[new session]\n")}; - mtx_push_op(d_user_state->output_log_key, op); - } - }break; - - case D_EventKind_DebugString: - { - MTX_Op op = {r1u64(max_U64, max_U64), event->string}; - mtx_push_op(d_user_state->output_log_key, op); - }break; } log_infof("}\n\n"); } @@ -1822,6 +1805,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P // rjf: push message to launch { D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs); + msg->msg_id = target->msg_id; msg->kind = D_MsgKind_Launch; msg->path = str8_copy(scratch.arena, working_directory); msg->cmd_line_string_list = str8_list_copy(scratch.arena, &cmdln_strings); diff --git a/src/dbg_engine/dbg_engine_user.h b/src/dbg_engine/dbg_engine_user.h index eac970b6..5bffd3f4 100644 --- a/src/dbg_engine/dbg_engine_user.h +++ b/src/dbg_engine/dbg_engine_user.h @@ -344,8 +344,8 @@ struct D_UserState Arena *cmds_arena; D_CmdList cmds; - // rjf: output log key - C_Key output_log_key; + // rjf: output log root + C_Root output_log_root; // rjf: per-run caches U64 tls_base_cache_reggen_idx; diff --git a/src/dbg_engine/generated/dbg_engine.meta.c b/src/dbg_engine/generated/dbg_engine.meta.c index 2d300773..e322fded 100644 --- a/src/dbg_engine/generated/dbg_engine.meta.c +++ b/src/dbg_engine/generated/dbg_engine.meta.c @@ -4,7 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -String8 d_entity_kind_code_name_table[12] = +String8 d_entity_kind_code_name_table[13] = { {0}, str8_lit_comp("root"), @@ -13,6 +13,7 @@ str8_lit_comp("process"), str8_lit_comp("thread"), str8_lit_comp("module"), str8_lit_comp("entry_point"), +str8_lit_comp("launch_msg_id"), str8_lit_comp("debug_info_path"), str8_lit_comp("pending_thread_name"), str8_lit_comp("pending_thread_color"), @@ -20,7 +21,7 @@ str8_lit_comp("breakpoint"), str8_lit_comp("address_range_annotation"), }; -String8 d_entity_kind_display_string_table[12] = +String8 d_entity_kind_display_string_table[13] = { {0}, str8_lit_comp("Root"), @@ -29,6 +30,7 @@ str8_lit_comp("Process"), str8_lit_comp("Thread"), str8_lit_comp("Module"), str8_lit_comp("EntryPoint"), +str8_lit_comp("LaunchMsgID"), str8_lit_comp("DebugInfoPath"), str8_lit_comp("PendingThreadName"), str8_lit_comp("PendingThreadColor"), diff --git a/src/dbg_engine/generated/dbg_engine.meta.h b/src/dbg_engine/generated/dbg_engine.meta.h index 31d446fe..d6983b68 100644 --- a/src/dbg_engine/generated/dbg_engine.meta.h +++ b/src/dbg_engine/generated/dbg_engine.meta.h @@ -54,6 +54,7 @@ D_EntityKind_Process, D_EntityKind_Thread, D_EntityKind_Module, D_EntityKind_EntryPoint, +D_EntityKind_LaunchMsgID, D_EntityKind_DebugInfoPath, D_EntityKind_PendingThreadName, D_EntityKind_PendingThreadColor, @@ -127,8 +128,8 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] = {&DEV_updating_indicator, str8_lit_comp("updating_indicator")}, }; C_LINKAGE_BEGIN -extern String8 d_entity_kind_code_name_table[12]; -extern String8 d_entity_kind_display_string_table[12]; +extern String8 d_entity_kind_code_name_table[13]; +extern String8 d_entity_kind_display_string_table[13]; extern U32 d_exception_code_kind_code_table[38]; extern String8 d_exception_code_kind_display_string_table[38]; extern String8 d_exception_code_kind_lowercase_code_string_table[38]; diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 3108cdbc..925f48f9 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -74,6 +74,7 @@ enum E_IRExtKind_Bytecode = RDI_EvalOp_COUNT, E_IRExtKind_SetSpace, E_IRExtKind_SetBaseOff, + E_IRExtKind_SetTLSOff, E_IRExtKind_COUNT }; diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 176d3d8e..07150263 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -62,7 +62,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[360] = +RD_VocabInfo rd_vocab_info_table[361] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -176,6 +176,7 @@ RD_VocabInfo rd_vocab_info_table[360] = {str8_lit_comp("path"), str8_lit_comp(""), str8_lit_comp("Path"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("guid"), str8_lit_comp(""), str8_lit_comp("GUID"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("peek_type"), str8_lit_comp("peek_types"), str8_lit_comp("Peek Type"), str8_lit_comp("Peek Types"), RD_IconKind_Null}, +{str8_lit_comp("output_label"), str8_lit_comp("output_labels"), str8_lit_comp("Output Label"), str8_lit_comp("Output Labels"), RD_IconKind_List}, {str8_lit_comp("launch_and_run"), str8_lit_comp(""), str8_lit_comp("Launch and Run"), str8_lit_comp(""), RD_IconKind_Play}, {str8_lit_comp("launch_and_step_into"), str8_lit_comp(""), str8_lit_comp("Launch and Step Into"), str8_lit_comp(""), RD_IconKind_PlayStepForward}, {str8_lit_comp("kill"), str8_lit_comp(""), str8_lit_comp("Kill"), str8_lit_comp(""), RD_IconKind_X}, @@ -456,7 +457,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[39] = {str8_lit_comp("color"), 1, str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Value\") @description(\"An expression to describe the value or location of the color.\")\n 'expression': expr_string,\n}\n")}, {str8_lit_comp("geo3d"), 1, str8_lit_comp("@inherit(tab) x:\n{\n @display_name(\"Expression\") @description(\"An expression to describe the base address of the index buffer.\")\n 'expression': expr_string,\n 'count': expr_string,\n 'vtx': expr_string,\n 'vtx_size': expr_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, {str8_lit_comp("getting_started"), 0, str8_lit_comp("@inherit(tab) x:\n{\n}\n")}, -{str8_lit_comp("target"), 0, str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n 'stdout_path': @no_relativize path,\n 'stderr_path': @no_relativize path,\n 'stdin_path': @no_relativize path,\n 'environment': set,\n 'debug_subprocesses': bool,\n @no_revert @no_expand @default(0) 'enabled': bool,\n}\n")}, +{str8_lit_comp("target"), 0, str8_lit_comp("@row_commands(@cmd_line save_cfg_to_project, enable_cfg, launch_and_run, launch_and_step_into, duplicate_cfg, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': expr_string,\n @default(\"output\") 'output_label': code_string,\n 'stdout_path': @no_relativize path,\n 'stderr_path': @no_relativize path,\n 'stdin_path': @no_relativize path,\n 'environment': set,\n 'debug_subprocesses': bool,\n @no_revert @no_expand @default(0) 'enabled': bool,\n}\n")}, {str8_lit_comp("breakpoint"), 0, str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint, add_function_breakpoint, clear_breakpoints)\nx:\n{\n 'label': code_string,\n 'condition': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")}, {str8_lit_comp("watch_pin"), 0, str8_lit_comp("@row_commands(duplicate_cfg, remove_cfg)\n@collection_commands(add_watch_pin, toggle_watch_pin)\nx:\n{\n 'expression': expr_string,\n 'source_location': path_pt,\n 'address_location': expr_string,\n}\n")}, {str8_lit_comp("debug_info"), 0, str8_lit_comp("@row_commands(enable_cfg, duplicate_cfg, remove_cfg)\n@collection_commands(load_debug_info)\nx:\n{\n 'path': @no_relativize path,\n @query 'guid': string,\n @no_revert @no_expand @default(1) 'enabled': bool,\n}\n")}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index a8b6ab71..1440f4db 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -603,7 +603,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[25]; extern String8 rd_tab_fast_path_query_name_table[25]; -extern RD_VocabInfo rd_vocab_info_table[360]; +extern RD_VocabInfo rd_vocab_info_table[361]; extern RD_NameSchemaInfo rd_name_schema_info_table[39]; extern String8 rd_reg_slot_code_name_table[49]; extern Rng1U64 rd_reg_slot_range_table[49]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 08d4c374..273c78c3 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -201,6 +201,7 @@ RD_VocabTable: {path "" "Path" "" FileOutline } {guid "" "GUID" "" Null } {peek_type _ "Peek Type" _ Null } + {output_label _ "Output Label" _ List } } @struct RD_VocabInfo: @@ -707,6 +708,7 @@ RD_VocabTable: 'arguments': string, 'working_directory': path, 'entry_point': expr_string, + @default("output") 'output_label': code_string, 'stdout_path': @no_relativize path, 'stderr_path': @no_relativize path, 'stdin_path': @no_relativize path, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d8360a3f..43163711 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -270,6 +270,7 @@ rd_target_from_cfg(Arena *arena, CFG_Node *cfg) target.stdout_path = cfg_node_child_from_string(cfg, str8_lit("stdout_path"))->first->string; target.stderr_path = cfg_node_child_from_string(cfg, str8_lit("stderr_path"))->first->string; target.stdin_path = cfg_node_child_from_string(cfg, str8_lit("stdin_path"))->first->string; + target.msg_id = cfg->id; target.debug_subprocesses = !!e_value_from_string(cfg_node_child_from_string(cfg, str8_lit("debug_subprocesses"))->first->string).u64; for(CFG_Node *child = cfg->first; child != &cfg_nil_node; child = child->next) { @@ -12332,21 +12333,33 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, macro_map, name, expr); } - //- rjf: add macro for output log + //- rjf: add macro for output logs { - Access *access = access_open(); - C_Key key = d_user_state->output_log_key; - U128 hash = c_hash_from_key(key, 0); - String8 data = c_data_from_hash(access, hash); - E_Space space = e_space_make(E_SpaceKind_HashStoreKey); - space.u64_0 = key.root.u64[0]; - space.u128 = key.id.u128[0]; - E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0); - e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("output"), expr); - access_close(access); + CFG_NodePtrList targets = cfg_node_top_level_list_from_string(scratch.arena, s("target")); + for EachNode(n, CFG_NodePtrNode, targets.first) + { + Access *access = access_open(); + CFG_Node *target = n->v; + CFG_Node *output_label = cfg_node_child_from_string(target, s("output_label")); + String8 output_label_string = output_label->first->string; + if(output_label_string.size == 0) + { + output_label_string = rd_default_setting_from_names(s("target"), s("output_label")); + } + C_ID id = {u128_hash_from_str8(output_label_string)}; + C_Key key = c_key_make(d_user_state->output_log_root, id); + U128 hash = c_hash_from_key(key, 0); + String8 data = c_data_from_hash(access, hash); + E_Space space = e_space_make(E_SpaceKind_HashStoreKey); + space.u64_0 = key.root.u64[0]; + space.u128 = key.id.u128[0]; + E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0)); + expr->space = space; + expr->mode = E_Mode_Offset; + expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0); + e_string2expr_map_insert(scratch.arena, macro_map, output_label_string, expr); + access_close(access); + } } //- rjf: (DEBUG) add macro for cfg strings @@ -15810,8 +15823,16 @@ rd_frame(void) //- rjf: output case RD_CmdKind_ClearOutput: { + // rjf: get output label + String8 output_label = rd_regs()->string; + + // rjf: output label -> key + C_ID id = {u128_hash_from_str8(output_label)}; + C_Key key = c_key_make(d_user_state->output_log_root, id); + + // rjf: clear MTX_Op op = {r1u64(0, 0xffffffffffffffffull), str8_lit("")}; - mtx_push_op(d_user_state->output_log_key, op); + mtx_push_op(key, op); }break; //- rjf: watch pins @@ -16955,6 +16976,11 @@ rd_frame(void) //////////////////////////// //- rjf: tick debug engine // + U64 process_count_pre_tick = 0; + { + D_EntityArray all_processes = d_entity_array_from_kind(D_EntityKind_Process); + process_count_pre_tick = all_processes.count; + } U64 cmd_count_pre_tick = rd_state->cmds[0].count; B32 soft_halt_issued = d_user_state->ctrl_soft_halt_issued; D_EventList engine_events = d_tick(scratch.arena, &targets, &breakpoints, &path_maps, exception_code_filters); @@ -16971,9 +16997,34 @@ rd_frame(void) case D_EventKind_NewProc: { D_EntityArray all_processes = d_entity_array_from_kind(D_EntityKind_Process); - if(all_processes.count == 1) + + // rjf: no processes before this one -> new session + if(process_count_pre_tick == 0) { + D_Entity *process = all_processes.v[0]; + CFG_Node *target = cfg_node_from_id(process->src_msg_id); + + // rjf: target -> output label + String8 output_label = cfg_node_child_from_string(target, s("output_label"))->first->string; + if(output_label.size == 0) + { + output_label = rd_default_setting_from_names(s("target"), s("output_label")); + } + + // rjf: output label -> key + C_ID id = {u128_hash_from_str8(output_label)}; + C_Key key = c_key_make(d_user_state->output_log_root, id); + + // rjf: reset output log for associated target + { + MTX_Op op = {r1u64(0, 0xffffffffffffffffull), str8_lit("[new session]\n")}; + mtx_push_op(key, op); + } + + // rjf: reset external window MemoryZeroStruct(&rd_state->prestop_focused_window); + + // rjf: eliminate all previously loaded debug infos CFG_NodePtrList dbg_infos = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("debug_info")); for EachNode(n, CFG_NodePtrNode, dbg_infos.first) { @@ -17138,6 +17189,26 @@ rd_frame(void) rd_state->last_stop_selected_thread_sp = new_sp; } }break; + case D_EventKind_DebugString: + { + // rjf: process -> src target's output label + D_Entity *process = d_entity_from_handle(evt->parent); + D_MsgID src_msg_id = process->src_msg_id; + CFG_Node *target = cfg_node_from_id(src_msg_id); + String8 output_label = cfg_node_child_from_string(target, s("output_label"))->first->string; + if(output_label.size == 0) + { + output_label = rd_default_setting_from_names(s("target"), s("output_label")); + } + + // rjf: output label -> key + C_ID id = {u128_hash_from_str8(output_label)}; + C_Key key = c_key_make(d_user_state->output_log_root, id); + + // rjf: push to keyed output + MTX_Op op = {r1u64(max_U64, max_U64), evt->string}; + mtx_push_op(key, op); + }break; } } diff --git a/src/win32/demon/win32_demon.c b/src/win32/demon/win32_demon.c index 329d0dfd..78f7d38f 100644 --- a/src/win32/demon/win32_demon.c +++ b/src/win32/demon/win32_demon.c @@ -2474,6 +2474,8 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) // rjf: unpack event W32_DMN_Entity *process = w32_dmn_entity_from_kind_id(W32_DMN_EntityKind_Process, evt.dwProcessId); W32_DMN_Entity *thread = w32_dmn_entity_from_kind_id(W32_DMN_EntityKind_Thread, evt.dwThreadId); + DMN_Handle process_handle = w32_dmn_handle_from_entity(process); + DMN_Handle thread_handle = w32_dmn_handle_from_entity(thread); U64 string_address = (U64)evt.u.DebugString.lpDebugStringData; U64 string_size = (U64)evt.u.DebugString.nDebugStringLength; @@ -2489,9 +2491,23 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) debug_string.size -= 1; } - // rjf: make debug string event - debug_strings_event = dmn_event_list_push(arena, &events); - debug_strings_event->kind = DMN_EventKind_DebugString; + // rjf: complete last debug string event, if we need to + if(debug_strings_event != 0 && !dmn_handle_match(process_handle, debug_strings_event->process)) + { + String8 debug_strings_joined = str8_list_join(arena, &debug_strings, 0); + debug_strings_event->string = debug_strings_joined; + debug_strings_event = 0; + MemoryZeroStruct(&debug_strings); + } + + // rjf: make debug string event if we need one + if(debug_strings_event == 0) + { + debug_strings_event = dmn_event_list_push(arena, &events); + debug_strings_event->kind = DMN_EventKind_DebugString; + debug_strings_event->process = process_handle; + debug_strings_event->thread = thread_handle; + } // rjf: push into debug strings str8_list_push(scratch.arena, &debug_strings, debug_string);