print out last captured output when a test fails or crashes

This commit is contained in:
Nikita Smith
2026-06-02 12:09:48 -07:00
committed by Ryan Fleury
parent a645622b10
commit 887ee21d94
7 changed files with 245 additions and 214 deletions
+77 -77
View File
@@ -10479,9 +10479,9 @@ rd_ipc_make_reply_stop_event(Arena *arena)
return result;
}
internal String8
rd_ipc_make_reply_eval(Arena *arena, String8 expr, E_Eval eval, U64 cap)
{
internal String8
rd_ipc_make_reply_eval(Arena *arena, String8 expr, E_Eval eval, U64 cap)
{
Temp scratch = scratch_begin(&arena, 1);
// gather value & type
@@ -10510,62 +10510,62 @@ rd_ipc_make_reply_eval(Arena *arena, String8 expr, E_Eval eval, U64 cap)
String8 result = str8_list_join(arena, &reply, 0);
scratch_end(scratch);
return result;
}
internal String8
rd_ipc_make_reply_source_location_from_address(Arena *arena, U64 vaddr)
{
Temp scratch = scratch_begin(&arena, 1);
D_Entity *process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_base_regs()->process);
if(process == &d_entity_nil)
{
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_base_regs()->thread);
process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
}
D_Entity *module = &d_entity_nil;
DI_Key dbgi_key = {0};
U64 voff = 0;
D_LineList lines = {0};
if(process != &d_entity_nil)
{
module = d_module_from_process_vaddr(process, vaddr);
if(module != &d_entity_nil)
{
dbgi_key = d_dbgi_key_from_module(module);
voff = d_voff_from_vaddr(module, vaddr);
lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, voff);
}
}
D_Line line = {0};
if(lines.first != 0)
{
line = lines.first->v;
}
B32 is_ok = (process != &d_entity_nil && module != &d_entity_nil && lines.first != 0);
String8List reply = {0};
rd_ipc_reply_block_begin(arena, &reply, "source_location_from_address");
rd_ipc_reply_push_b32 (arena, &reply, "ok", is_ok);
rd_ipc_reply_push_u64 (arena, &reply, "vaddr", vaddr);
rd_ipc_reply_push_u64 (arena, &reply, "voff", voff);
rd_ipc_reply_push_str8(arena, &reply, "file_path", line.file_path);
rd_ipc_reply_push_u64 (arena, &reply, "line", line.pt.line);
rd_ipc_reply_push_u64 (arena, &reply, "column", line.pt.column);
rd_ipc_reply_push_u64 (arena, &reply, "voff_min", line.voff_range.min);
rd_ipc_reply_push_u64 (arena, &reply, "voff_max", line.voff_range.max);
rd_ipc_reply_block_end(arena, &reply);
String8 result = str8_list_join(arena, &reply, 0);
scratch_end(scratch);
return result;
}
////////////////////////////////
//~ rjf: Main Layer Top-Level Calls
return result;
}
internal String8
rd_ipc_make_reply_source_location_from_address(Arena *arena, U64 vaddr)
{
Temp scratch = scratch_begin(&arena, 1);
D_Entity *process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_base_regs()->process);
if(process == &d_entity_nil)
{
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_base_regs()->thread);
process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
}
D_Entity *module = &d_entity_nil;
DI_Key dbgi_key = {0};
U64 voff = 0;
D_LineList lines = {0};
if(process != &d_entity_nil)
{
module = d_module_from_process_vaddr(process, vaddr);
if(module != &d_entity_nil)
{
dbgi_key = d_dbgi_key_from_module(module);
voff = d_voff_from_vaddr(module, vaddr);
lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, voff);
}
}
D_Line line = {0};
if(lines.first != 0)
{
line = lines.first->v;
}
B32 is_ok = (process != &d_entity_nil && module != &d_entity_nil && lines.first != 0);
String8List reply = {0};
rd_ipc_reply_block_begin(arena, &reply, "source_location_from_address");
rd_ipc_reply_push_b32 (arena, &reply, "ok", is_ok);
rd_ipc_reply_push_u64 (arena, &reply, "vaddr", vaddr);
rd_ipc_reply_push_u64 (arena, &reply, "voff", voff);
rd_ipc_reply_push_str8(arena, &reply, "file_path", line.file_path);
rd_ipc_reply_push_u64 (arena, &reply, "line", line.pt.line);
rd_ipc_reply_push_u64 (arena, &reply, "column", line.pt.column);
rd_ipc_reply_push_u64 (arena, &reply, "voff_min", line.voff_range.min);
rd_ipc_reply_push_u64 (arena, &reply, "voff_max", line.voff_range.max);
rd_ipc_reply_block_end(arena, &reply);
String8 result = str8_list_join(arena, &reply, 0);
scratch_end(scratch);
return result;
}
////////////////////////////////
//~ rjf: Main Layer Top-Level Calls
#if !defined(STBI_INCLUDE_STB_IMAGE_H)
# define STB_IMAGE_IMPLEMENTATION
@@ -12906,24 +12906,24 @@ rd_frame(void)
rd_cmd(RD_CmdKind_StepIntoLine);
str8_list_push(rd_state->cmd_output_arena, &rd_state->cmd_outputs, rd_ipc_make_reply_ack(rd_state->cmd_output_arena, str8_lit("step_into_line"), 1));
}
else if(str8_match(cmd_kind_name, str8_lit("eval"), 0))
{
U64 cap_end = str8_find_needle(cmd_args, 0, str8_lit(" "), 0);
String8 cap_str = str8_substr(cmd_args, r1u64(0, cap_end));
U64 cap = 0;
try_u64_from_str8_c_rules(cap_str, &cap);
String8 expr = str8_skip(cmd_args, cap_str.size);
str8_list_push(rd_state->cmd_output_arena, &rd_state->cmd_outputs, rd_ipc_make_reply_eval(rd_state->cmd_output_arena, expr, e_eval_from_string(expr), cap));
}
else if(str8_match(cmd_kind_name, str8_lit("source_location_from_address"), 0))
{
String8 vaddr_str = str8_skip_chop_whitespace(cmd_args);
U64 vaddr = 0;
try_u64_from_str8_c_rules(vaddr_str, &vaddr);
str8_list_push(rd_state->cmd_output_arena, &rd_state->cmd_outputs, rd_ipc_make_reply_source_location_from_address(rd_state->cmd_output_arena, vaddr));
}
else if(cmd_kind_info != &rd_nil_cmd_kind_info) RD_RegsScope()
{
else if(str8_match(cmd_kind_name, str8_lit("eval"), 0))
{
U64 cap_end = str8_find_needle(cmd_args, 0, str8_lit(" "), 0);
String8 cap_str = str8_substr(cmd_args, r1u64(0, cap_end));
U64 cap = 0;
try_u64_from_str8_c_rules(cap_str, &cap);
String8 expr = str8_skip(cmd_args, cap_str.size);
str8_list_push(rd_state->cmd_output_arena, &rd_state->cmd_outputs, rd_ipc_make_reply_eval(rd_state->cmd_output_arena, expr, e_eval_from_string(expr), cap));
}
else if(str8_match(cmd_kind_name, str8_lit("source_location_from_address"), 0))
{
String8 vaddr_str = str8_skip_chop_whitespace(cmd_args);
U64 vaddr = 0;
try_u64_from_str8_c_rules(vaddr_str, &vaddr);
str8_list_push(rd_state->cmd_output_arena, &rd_state->cmd_outputs, rd_ipc_make_reply_source_location_from_address(rd_state->cmd_output_arena, vaddr));
}
else if(cmd_kind_info != &rd_nil_cmd_kind_info) RD_RegsScope()
{
for EachNonZeroEnumVal(RD_RegSlot, s)
{
String8 reg_slot_name = rd_reg_slot_code_name_table[s];