symbol server abstraction layer; http layer; fix to 'prefer_disasm' rule when no disassembly tabs are open; small fixes / cleanup

This commit is contained in:
Ryan Fleury
2026-06-08 11:10:14 -07:00
parent 1ef94cb759
commit 5c664261a3
38 changed files with 1347 additions and 81 deletions
+4 -2
View File
@@ -626,7 +626,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[255] =
{ str8_lit_comp("open_crash_dump"), str8_lit_comp("Opens a crash dump file and recreates debuggee state at the time of the crash."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(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_FilePath, str8_lit_comp("folder:\"$input\""), str8_lit_comp(""), D_EntityKind_Null}},
{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*0)|(RD_CmdKindFlag_ListInMemory*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("open_palette"), str8_lit_comp("Opens the palette."), str8_lit_comp("help,cmd,lister"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*0)|(RD_CmdKindFlag_ListInMemory*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("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*0)|(RD_CmdKindFlag_ListInMemory*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_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), D_EntityKind_Null}},
{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0)|(RD_CmdKindFlag_ListInTextPt*0)|(RD_CmdKindFlag_ListInTextRng*0)|(RD_CmdKindFlag_ListInEval*0)|(RD_CmdKindFlag_ListInMemory*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_CmdName, str8_lit_comp("query:commands"), str8_lit_comp("commands"), D_EntityKind_Null}},
{ str8_lit_comp("run_ext_driver_text_command"), str8_lit_comp(""), 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_CmdKindFlag_ListInMemory*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("state"), str8_lit_comp(""), 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_CmdKindFlag_ListInMemory*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("eval"), str8_lit_comp(""), 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_CmdKindFlag_ListInMemory*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_Expr, str8_lit_comp(""), str8_lit_comp(""), D_EntityKind_Null}},
@@ -845,7 +845,7 @@ RD_CmdKindInfo rd_cmd_kind_info_table[255] =
{ str8_lit_comp("geo3d"), str8_lit_comp("Opens a Geometry (3D) tab."), {0}, {0}, RD_CmdKindFlag_ListInUI|RD_CmdKindFlag_ListInIPCDocs|RD_CmdKindFlag_ListInTab},
};
struct {String8 string; CFG_Binding binding;} rd_default_binding_table[114] =
struct {String8 string; CFG_Binding binding;} rd_default_binding_table[116] =
{
{str8_lit_comp("kill_all"), {WM_Key_F5, 0 |WM_Modifier_Shift }},
{str8_lit_comp("step_into_inst"), {WM_Key_F11, 0 |WM_Modifier_Alt}},
@@ -944,7 +944,9 @@ struct {String8 string; CFG_Binding binding;} rd_default_binding_table[114] =
{str8_lit_comp("goto_line"), {WM_Key_G, 0 |WM_Modifier_Ctrl }},
{str8_lit_comp("goto_address"), {WM_Key_G, 0 |WM_Modifier_Alt}},
{str8_lit_comp("search"), {WM_Key_F, 0 |WM_Modifier_Ctrl }},
{str8_lit_comp("search"), {WM_Key_Slash, 0 }},
{str8_lit_comp("search_backwards"), {WM_Key_R, 0 |WM_Modifier_Ctrl }},
{str8_lit_comp("search_backwards"), {WM_Key_Slash, 0 |WM_Modifier_Ctrl }},
{str8_lit_comp("find_next"), {WM_Key_F3, 0 }},
{str8_lit_comp("find_prev"), {WM_Key_F3, 0 |WM_Modifier_Ctrl }},
{str8_lit_comp("find_selected_thread"), {WM_Key_F4, 0 }},
+3 -1
View File
@@ -949,7 +949,7 @@ RD_CmdTable: // | | | |
{OpenPalette 1 1 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 List "open_palette" "Open Palette" "Opens the palette." "help,cmd,lister" "" }
//- rjf: command fast-path
{RunCommand 1 1 0 0 0 0 "query:commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" }
{RunCommand 0 0 0 0 0 0 "query:commands" CmdName commands Nil Null 0 0 0 0 0 1 1 Null "run_command" "Run Command" "Runs a command from the command palette." "help,cmd" "" }
//- rjf: external drivers
{RunExternalDriverTextCommand 0 0 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "run_ext_driver_text_command" "Run External Driver Text Command" "" "" "" }
@@ -1415,7 +1415,9 @@ RD_DefaultBindingTable:
{ "goto_line" G ctrl 0 0 }
{ "goto_address" G 0 0 alt }
{ "search" F ctrl 0 0 }
{ "search" Slash 0 0 0 }
{ "search_backwards" R ctrl 0 0 }
{ "search_backwards" Slash ctrl 0 0 }
{ "find_next" F3 0 0 0 }
{ "find_prev" F3 shift 0 0 }
+87 -4
View File
@@ -1685,7 +1685,7 @@ rd_view_ui(Rng2F32 rect)
//- rjf: build container
UI_Box *search_row = &ui_nil_box;
UI_PrefHeight(ui_px(search_row_height, 1.f)) UI_TagF("focus")
UI_PrefHeight(ui_px(search_row_height, 1.f)) // UI_TagF("focus")
{
if(!vs->contents_are_focused)
{
@@ -6633,12 +6633,19 @@ rd_window_frame(void)
UI_PermissionFlag_KeyboardSecondary|UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX|UI_PermissionFlag_ScrollY :
UI_PermissionFlag_All)
{
B32 has_footer = (is_lister && !is_anchored);
F32 container_corner_top_radius_px = is_lister ? ui_top_font_size()*1.f : ui_top_font_size()*0.15f;
F32 container_corner_bottom_radius_px = has_footer ? ui_top_font_size()*1.f : ui_top_font_size()*0.15f;
// rjf: build top-level container box
UI_Box *container = &ui_nil_box;
UI_Rect(rect) UI_ChildLayoutAxis(Axis2_Y)
UI_Squish(0.1f-0.1f*open_t)
UI_Transparency(1.f-open_t)
UI_CornerRadius(ui_top_font_size()*0.25f)
UI_CornerRadius00(container_corner_top_radius_px)
UI_CornerRadius10(container_corner_top_radius_px)
UI_CornerRadius01(container_corner_bottom_radius_px)
UI_CornerRadius11(container_corner_bottom_radius_px)
{
container = ui_build_box_from_stringf(UI_BoxFlag_Clickable|
UI_BoxFlag_DrawBorder|
@@ -6680,7 +6687,7 @@ rd_window_frame(void)
// rjf: build contents
F32 total_height_px = dim_2f32(rect).y;
F32 footer_height_px = 0;
if(is_lister && !is_anchored)
if(has_footer)
{
footer_height_px = ui_top_font_size()*4.f;
}
@@ -7573,6 +7580,29 @@ rd_window_frame(void)
ui_label(str8_lit(BUILD_TITLE_STRING_LITERAL));
}
// rjf: update available?
if(rd_state->newer_update_available)
UI_FontSize(ui_top_font_size()*0.85f)
UI_PrefWidth(ui_text_dim(10, 1))
UI_TextAlignment(UI_TextAlign_Center)
{
DR_FStrList fstrs = {0};
ui_set_next_hover_cursor(WM_Cursor_HandPoint);
UI_Box *label = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_DrawText, "##update");
UI_Signal sig = ui_signal_from_box(label);
DR_FStrParams p = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(s("text")), ui_top_font_size()};
if(ui_key_match(ui_hot_key(), label->key))
{
p.underline_thickness = ui_top_font_size()*0.2f;
}
dr_fstrs_push_new(scratch.arena, &fstrs, &p, s("Update Available"));
ui_box_equip_display_fstrs(label, &fstrs);
if(ui_clicked(sig))
{
wm_open_in_browser(s("https://github.com/EpicGamesExt/raddebugger/releases/latest"));
}
}
scratch_end(scratch);
}
}
@@ -7910,6 +7940,7 @@ rd_window_frame(void)
//
if(content_rect.x1 > content_rect.x0 && content_rect.y1 > content_rect.y0)
{
B32 any_disasm_open = 0;
ProfScope("leaf panel UI")
for(CFG_PanelNode *panel = panel_tree.root;
panel != &cfg_nil_panel_node;
@@ -7924,6 +7955,10 @@ rd_window_frame(void)
panel_tree.focused == panel);
CFG_Node *selected_tab = panel->selected_tab;
RD_ViewState *selected_tab_view_state = rd_view_state_from_cfg(selected_tab);
if(str8_match(selected_tab->string, s("disasm"), 0))
{
any_disasm_open = 1;
}
ProfScope("leaf panel UI work - %.*s: %.*s", str8_varg(selected_tab->string), str8_varg(rd_expr_from_cfg(selected_tab)))
UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off)
{
@@ -8752,6 +8787,10 @@ rd_window_frame(void)
}
}
}
if(!any_disasm_open && rd_regs()->prefer_disasm)
{
rd_regs()->prefer_disasm = 0;
}
}
////////////////////////////
@@ -9342,6 +9381,8 @@ rd_window_frame(void)
FNT_Tag font = rd_font_from_slot(RD_FontSlot_Code);
Vec2F32 p = ui_mouse();
dr_rect(hover_debug_box->rect, v4f32(1, 1, 1, 0.2f), 0, 0, 0);
R_Rect2DInst *border = dr_rect(hover_debug_box->rect, v4f32(1, 0, 0, 1.f), 0, 0, 0);
MemoryCopyArray(border->corner_radii, hover_debug_box->corner_radii);
dr_text(font, 12.f, 0, 0, FNT_RasterFlag_Hinted, p, v4f32(1, 1, 1, 1), push_str8f(scratch.arena, "key: 0x%I64x", hover_debug_box->key.u64[0]));
p.y += 20.f;
dr_text(font, 12.f, 0, 0, FNT_RasterFlag_Hinted, p, v4f32(1, 1, 1, 1), push_str8f(scratch.arena, "string: '%S'", hover_debug_box->string));
@@ -10641,6 +10682,19 @@ rd_init(CmdLine *cmdln)
rd_state->drag_drop_regs = push_array(rd_state->drag_drop_arena, RD_Regs, 1);
rd_state->top_regs = &rd_state->base_regs;
// rjf: set up update check http ring & send request
{
rd_state->update_check_http_ring = guarded_ring_alloc(arena, KB(8));
HTTP_RequestParams p =
{
.id = 1,
.method = HTTP_Method_Get,
.url = s("https://api.github.com/repos/EpicGamesExt/raddebugger/releases/latest"),
.user_agent = s("raddebugger"),
};
http_push_request(rd_state->update_check_http_ring, &p, 0);
}
// rjf: set up schemas
{
rd_state->cfg_schema_table = push_array(rd_state->arena, CFG_SchemaTable, 1);
@@ -11043,6 +11097,33 @@ rd_frame(void)
MemoryZeroStruct(&rd_state->cmd_outputs);
}
//////////////////////////////
//- rjf: check for updates
//
if(!rd_state->got_update_check)
{
Temp scratch = scratch_begin(0, 0);
HTTP_Response response = {0};
if(http_pop_response(scratch.arena, rd_state->update_check_http_ring, &response, 0))
{
rd_state->got_update_check = 1;
MD_Node *root = md_tree_from_string(scratch.arena, response.body)->first;
MD_Node *html_url = md_child_from_string(root, s("html_url"), 0);
String8 newest_release_url = html_url->first->string;
U64 tag_pos = str8_find_needle(newest_release_url, 0, s("tag/v"), 0);
String8 tag_name = str8_skip(newest_release_url, tag_pos);
U64 suffix_pos = str8_find_needle(tag_name, 0, s("-"), 0);
String8 version_name = str8_prefix(tag_name, suffix_pos);
U64 release_version = version_from_str8(version_name);
U64 current_version = Version(BUILD_VERSION_MAJOR, BUILD_VERSION_MINOR, BUILD_VERSION_PATCH);
if(current_version < release_version)
{
rd_state->newer_update_available = 1;
}
}
scratch_end(scratch);
}
//////////////////////////////
//- rjf: iterate all tabs, touch their view-states
//
@@ -11082,6 +11163,7 @@ rd_frame(void)
//////////////////////////////
//- rjf: apply debug info config trees -> loaded debug info cache
//
ProfScope("apply debug info config trees -> loaded debug info cache")
{
U64 current_update_tick_idx = update_tick_idx();
@@ -12883,7 +12965,8 @@ rd_frame(void)
{
rd_cmd(RD_CmdKind_PushQuery,
.do_implicit_root = 1,
.do_lister = info->query.expr.size != 0);
.do_lister = (info->query.expr.size != 0),
.expr = info->query.expr);
}
}break;
+5
View File
@@ -394,6 +394,11 @@ struct RD_State
S32 frame_depth;
U64 frame_eval_memread_endt_us;
// rjf: update checker
B32 got_update_check;
B32 newer_update_available;
GuardedRing *update_check_http_ring;
// rjf: config bucket paths
Arena *user_path_arena;
String8 user_path;
+9 -4
View File
@@ -4,6 +4,7 @@
////////////////////////////////
//~ rjf: post-0.9.26 TODO notes
//
// [ ] unwinding crash - f5 on bp in w32_http_status_callback to repro
// [ ] jeff stepping bug
// [ ] wassim memory bug
// [ ] switch off spoofs for step-over
@@ -309,6 +310,8 @@
#include "minidump/minidump_parse.h"
#include "mdesk/mdesk.h"
#include "window_manager/window_manager_inc.h"
#include "http/http_inc.h"
#include "symbol_server/symbol_server_inc.h"
#include "config/config_inc.h"
#include "content/content.h"
#include "file_stream/file_stream.h"
@@ -366,6 +369,8 @@
#include "minidump/minidump_parse.c"
#include "mdesk/mdesk.c"
#include "window_manager/window_manager_inc.c"
#include "http/http_inc.c"
#include "symbol_server/symbol_server_inc.c"
#include "config/config_inc.c"
#include "content/content.c"
#include "file_stream/file_stream.c"
@@ -468,8 +473,8 @@ ipc_signaler_thread__entry_point(void *p)
U64 available_size = (sizeof(ipc_s2m_ring_buffer) - unconsumed_size);
if(available_size >= sizeof(U64)+sizeof(msg.size))
{
ipc_s2m_ring_write_pos += ring_write_struct(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_write_pos, &msg.size);
ipc_s2m_ring_write_pos += ring_write(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_write_pos, msg.str, msg.size);
ipc_s2m_ring_write_pos += wrapped_write_struct(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_write_pos, &msg.size);
ipc_s2m_ring_write_pos += wrapped_write(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_write_pos, msg.str, msg.size);
break;
}
cond_var_wait(ipc_s2m_ring_cv, ipc_s2m_ring_mutex, max_U64);
@@ -659,10 +664,10 @@ entry_point(CmdLine *cmd_line)
{
consumed = 1;
ipc_command_frame = 1;
ipc_s2m_ring_read_pos += ring_read_struct(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_read_pos, &msg.size);
ipc_s2m_ring_read_pos += wrapped_read_struct(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_read_pos, &msg.size);
msg.size = Min(msg.size, unconsumed_size);
msg.str = push_array(scratch.arena, U8, msg.size);
ipc_s2m_ring_read_pos += ring_read(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_read_pos, msg.str, msg.size);
ipc_s2m_ring_read_pos += wrapped_read(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_read_pos, msg.str, msg.size);
}
}
if(consumed)
+2 -2
View File
@@ -2543,12 +2543,12 @@ RD_VIEW_UI_FUNCTION_DEF(disasm)
}
//////////////////////////////
//- rjf: unpack cursor info
//- rjf: unpack cursor info / fill regs
//
rd_regs()->prefer_disasm = 1;
if(!is_loading && has_disasm)
{
U64 off = dasm_line_array_code_off_from_idx(&dasm_info.lines, rd_regs()->cursor.line-1);
rd_regs()->prefer_disasm = 1;
rd_regs()->vaddr = range.min+off;
rd_regs()->vaddr_range = r1u64(range.min+off, range.min+off);
rd_regs()->voff_range = d_voff_range_from_vaddr_range(dasm_module, rd_regs()->vaddr_range);