diff --git a/src/dbg_engine/dbg_engine_ctrl.c b/src/dbg_engine/dbg_engine_ctrl.c index 918390fc..7b2ff413 100644 --- a/src/dbg_engine/dbg_engine_ctrl.c +++ b/src/dbg_engine/dbg_engine_ctrl.c @@ -2533,10 +2533,15 @@ d_ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, D_EvalScope *e else if(bp->vaddr_expr.size != 0) { String8 expr = bp->vaddr_expr; - E_Value value = e_value_from_string(expr); - if(value.u64 != 0 || bp->flags != 0) + E_Eval eval = e_eval_from_string(expr); + U64 vaddr = eval.value.u64; + if(eval.irtree.mode == E_Mode_Value) { - DMN_Trap trap = {process_dmn, value.u64, (U64)bp}; + vaddr = e_value_eval_from_eval(eval).value.u64; + } + if(vaddr != 0 || bp->flags != 0) + { + DMN_Trap trap = {process_dmn, vaddr, (U64)bp}; trap.flags = d_dmn_trap_flags_from_breakpoint_flags(bp->flags); trap.size = bp->size; dmn_trap_chunk_list_push(arena, traps_out, 256, &trap); diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 615c7b7c..d0e2a890 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[366] = +RD_VocabInfo rd_vocab_info_table[367] = { {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}, @@ -392,6 +392,7 @@ RD_VocabInfo rd_vocab_info_table[366] = {str8_lit_comp("register_as_jit_debugger"), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("find_code_location"), str8_lit_comp(""), str8_lit_comp("Find Code Location"), str8_lit_comp(""), RD_IconKind_FileOutline}, {str8_lit_comp("go_to_memory"), str8_lit_comp(""), str8_lit_comp("Go To Memory"), str8_lit_comp(""), RD_IconKind_Grid}, +{str8_lit_comp("break_when_value_changes"), str8_lit_comp(""), str8_lit_comp("Break When Value Changes"), str8_lit_comp(""), RD_IconKind_CircleFilled}, {str8_lit_comp("search"), str8_lit_comp(""), str8_lit_comp("Search"), str8_lit_comp(""), RD_IconKind_Find}, {str8_lit_comp("search_backwards"), str8_lit_comp(""), str8_lit_comp("Search Backwards"), str8_lit_comp(""), RD_IconKind_Find}, {str8_lit_comp("pick_file"), str8_lit_comp(""), str8_lit_comp("Pick File"), str8_lit_comp(""), RD_IconKind_FileOutline}, @@ -583,7 +584,7 @@ Rng1U64 rd_reg_slot_range_table[50] = {OffsetOf(RD_Regs, wm_event), OffsetOf(RD_Regs, wm_event) + sizeof(WM_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[254] = +RD_CmdKindInfo rd_cmd_kind_info_table[255] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), D_EntityKind_Null}}, @@ -800,7 +801,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[254] = { str8_lit_comp("remove_target"), str8_lit_comp("Removes a target."), str8_lit_comp("delete"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets"), str8_lit_comp(""), D_EntityKind_Null}}, { str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}}, { str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}}, -{ str8_lit_comp("go_to_memory"), str8_lit_comp("Finds the specified expression in the memory view. Opens the memory view if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*0), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}}, +{ str8_lit_comp("go_to_memory"), str8_lit_comp("Finds the specified expression in the memory view. Opens the memory view if necessary."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*0), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}}, +{ str8_lit_comp("break_when_value_changes"), str8_lit_comp("Adds a new write data breakpoint for this variable's range."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*0), RD_RegSlot_Expr, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}}, { str8_lit_comp("search"), str8_lit_comp("Begins searching within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}}, { str8_lit_comp("search_backwards"), str8_lit_comp("Begins searching backwards within the active interface."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*1)|(RD_QueryFlag_KeepOldInput*1)|(RD_QueryFlag_SelectOldInput*1)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}}, { str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*0), {(RD_QueryFlag_AllowFiles*1)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), D_EntityKind_Null}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 3bcab9e5..2a0a5007 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -279,6 +279,7 @@ RD_CmdKind_RemoveTarget, RD_CmdKind_RegisterAsJITDebugger, RD_CmdKind_FindCodeLocation, RD_CmdKind_GoToMemory, +RD_CmdKind_BreakWhenValueChanges, RD_CmdKind_Search, RD_CmdKind_SearchBackwards, RD_CmdKind_PickFile, @@ -611,7 +612,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[366]; +extern RD_VocabInfo rd_vocab_info_table[367]; extern RD_NameSchemaInfo rd_name_schema_info_table[39]; extern String8 rd_reg_slot_code_name_table[50]; extern Rng1U64 rd_reg_slot_range_table[50]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 9ca85783..1bb8530c 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1205,7 +1205,10 @@ RD_CmdTable: // | | | | {FindCodeLocation 0 1 0 0 0 "" FilePath null Nil Null 0 0 0 0 0 1 1 FileOutline "find_code_location" "Find Code Location" "Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary." "" "" } //- rjf: snap-to-memory-location - {GoToMemory 1 1 0 0 1 "" Expr null Nil Null 0 0 0 0 1 1 0 Grid "go_to_memory" "Go To Memory" "Finds the specified expression in the memory view. Opens the memory view if necessary." "" "" } + {GoToMemory 0 1 0 0 1 "" Expr null Nil Null 0 0 0 0 1 1 0 Grid "go_to_memory" "Go To Memory" "Finds the specified expression in the memory view. Opens the memory view if necessary." "" "" } + + //- rjf: break-when-value-changes + {BreakWhenValueChanges 0 1 0 0 1 "" Expr null Nil Null 0 0 0 0 1 1 0 CircleFilled "break_when_value_changes" "Break When Value Changes" "Adds a new write data breakpoint for this variable's range." "" "" } //- rjf: searching {Search 1 1 0 0 0 "" String null Nil Null 0 0 1 1 1 0 1 Find "search" "Search" "Begins searching within the active interface." "sort,search,filter,find" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 812ae256..55fadecf 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -4129,8 +4129,13 @@ rd_view_ui(Rng2F32 rect) // rjf: apply bindings if(cell->px == 0 && cell->eval.space.kind == RD_EvalSpaceKind_MetaCmd) { - cell_params.flags |= RD_CellFlag_Bindings; - cell_params.bindings_name = rd_cmd_name_from_eval(cell->eval); + String8 cmd_name = rd_cmd_name_from_eval(cell->eval); + RD_CmdKindInfo *info = rd_cmd_kind_info_from_string(cmd_name); + if(info->flags & RD_CmdKindFlag_ListInUI) + { + cell_params.flags |= RD_CellFlag_Bindings; + cell_params.bindings_name = cmd_name; + } } // rjf: apply background override @@ -15622,6 +15627,28 @@ rd_frame(void) } }break; + //- rjf: break-when-value-changes + case RD_CmdKind_BreakWhenValueChanges: + { + E_Eval eval = e_eval_from_string(rd_regs()->expr); + U64 size = e_type_byte_size_from_key(eval.irtree.type_key); + U64 bp_range_size = 1; + if(size > bp_range_size) {bp_range_size = 2;} + if(size > bp_range_size) {bp_range_size = 4;} + if(size > bp_range_size) {bp_range_size = 8;} + CFG_Node *user = cfg_node_child_from_string(cfg_node_root(), s("user")); + CFG_Node *bp = cfg_node_new(rd_state->cfg, user, s("breakpoint")); + CFG_Node *project = cfg_node_new(rd_state->cfg, bp, s("project")); + cfg_node_new(rd_state->cfg, project, rd_state->project_path); + CFG_Node *addr_loc = cfg_node_new(rd_state->cfg, bp, s("address_location")); + cfg_node_new(rd_state->cfg, addr_loc, rd_regs()->expr); + CFG_Node *rng = cfg_node_new(rd_state->cfg, bp, s("address_range_size")); + cfg_node_newf(rd_state->cfg, rng, "%I64u", bp_range_size); + CFG_Node *brk = cfg_node_new(rd_state->cfg, bp, s("break_on_write")); + cfg_node_new(rd_state->cfg, brk, s("1")); + str8_list_pushf(rd_state->cmd_output_arena, &rd_state->cmd_outputs, "$%I64x", bp->id); + }break; + //- rjf: queries case RD_CmdKind_PushQuery: { diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index e897e263..a1355099 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -30,11 +30,12 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(commands) for EachNonZeroEnumVal(RD_CmdKind, k) { RD_CmdKindInfo *info = &rd_cmd_kind_info_table[k]; - if(info->flags & RD_CmdKindFlag_ListInUI && - (!str8_match(type->name, s("text_pt_commands"), 0) || info->flags & RD_CmdKindFlag_ListInTextPt) && - (!str8_match(type->name, s("text_range_commands"), 0) || info->flags & RD_CmdKindFlag_ListInTextRng) && - (!str8_match(type->name, s("tab_commands"), 0) || info->flags & RD_CmdKindFlag_ListInTab) && - (!str8_match(type->name, s("eval_commands"), 0) || info->flags & RD_CmdKindFlag_ListInEval)) + B32 show = ((str8_match(type->name, s("commands"), 0) && info->flags & RD_CmdKindFlag_ListInUI) || + (str8_match(type->name, s("text_pt_commands"), 0) && info->flags & RD_CmdKindFlag_ListInTextPt) || + (str8_match(type->name, s("text_range_commands"), 0) && info->flags & RD_CmdKindFlag_ListInTextRng) || + (str8_match(type->name, s("tab_commands"), 0) && info->flags & RD_CmdKindFlag_ListInTab) || + (str8_match(type->name, s("eval_commands"), 0) && info->flags & RD_CmdKindFlag_ListInEval)); + if(show) { String8 code_name = info->string; String8 description = info->description; diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 9bd8a16b..3fceac67 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1430,7 +1430,6 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe line_num += 1, line_idx += 1) { D_EntityList line_ips = params->line_ips[line_idx]; - ui_set_next_hover_cursor(WM_Cursor_HandPoint); UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); UI_Parent(line_margin_box) { @@ -1585,9 +1584,9 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe D_EntityList line_ips = params->line_ips[line_idx]; CFG_NodePtrList line_bps = params->line_bps[line_idx]; CFG_NodePtrList line_pins = params->line_pins[line_idx]; - ui_set_next_hover_cursor(WM_Cursor_HandPoint); ui_set_next_background_color(v4f32(0, 0, 0, 0)); - UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); + ui_set_next_text_alignment(UI_TextAlign_Center); + UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & RD_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawText|UI_BoxFlag_DrawActiveEffects, "###line_margin_%I64x", line_num); UI_Parent(line_margin_box) { //- rjf: build margin thread ip ui @@ -1856,6 +1855,15 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // rjf: empty margin interaction UI_Signal line_margin_sig = ui_signal_from_box(line_margin_box); + if(ui_hovering(line_margin_sig)) + { + DR_FStrList fstrs = {0}; + Vec4F32 color = ui_color_from_name(s("breakpoint")); + color.w *= 0.2f; + DR_FStrParams p = {rd_font_from_slot(RD_FontSlot_Icons), rd_raster_flags_from_slot(RD_FontSlot_Icons), color, ui_top_font_size()}; + dr_fstrs_push_new(scratch.arena, &fstrs, &p, rd_icon_kind_text_table[RD_IconKind_CircleFilled]); + ui_box_equip_display_fstrs(line_margin_box, &fstrs); + } if(ui_clicked(line_margin_sig)) { rd_cmd(RD_CmdKind_AddBreakpoint,