WIP DWARF line table conversion tester

This commit is contained in:
Nikita Smith
2026-02-24 18:05:39 -08:00
parent 03445022d5
commit c7f7e15434
5 changed files with 282 additions and 40 deletions
+98 -33
View File
@@ -91,25 +91,73 @@ t_run(T_Run run)
return ctx.result;
}
internal B32
t_invoke(String8 exe_path, String8 cmdline, U64 timeout)
internal String8
t_radbin_path(void)
{
Temp scratch = scratch_begin(0,0);
local_persist String8 path = {0};
if (path.size == 0) {
local_persist U8 buffer[4096];
ArenaParams params = { .reserve_size = sizeof(buffer), .commit_size = sizeof(buffer), .optional_backing_buffer = buffer };
Arena *arena = arena_alloc_(&params);
#if OS_WINDOWS
path = os_full_path_from_path(arena, str8_lit("radbin.exe"));
#else
path = os_full_path_from_path(arena, str8_lit("radbin"));
#endif
AssertAlways(path.size);
}
return path;
}
internal String8
t_radlink_path(void)
{
local_persist String8 path = {0};
if (path.size == 0) {
local_persist U8 buffer[4096];
ArenaParams params = { .reserve_size = sizeof(buffer), .commit_size = sizeof(buffer), .optional_backing_buffer = buffer };
Arena *arena = arena_alloc_(&params);
#if OS_WINDOWS
path = os_full_path_from_path(arena, str8_lit("radlink.exe"));
#else
path = os_full_path_from_path(arena, str8_lit("radlink"));
#endif
AssertAlways(path.size);
}
return path;
}
internal B32
t_invoke_(String8 exe_path, String8 cmdline, U64 timeout, Arena *output_arena, String8 *output_out)
{
Temp scratch = scratch_begin(&output_arena,1);
B32 is_ok = 0;
OS_Handle output_redirect = {0};
if (g_redirect_stdout) {
output_redirect = os_file_open(OS_AccessFlag_Append|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, g_stdout_file_name);
B32 capture_output = output_out || g_redirect_stdout;
g_last_exit_code = -1;
OS_Handle read_pipe_handle = {0}, write_pipe_handle = {0};
if (capture_output) {
HANDLE read_pipe, write_pipe;
SECURITY_ATTRIBUTES at = { .nLength = sizeof(at), .bInheritHandle = 1 };
if (!CreatePipe(&read_pipe, &write_pipe, &at, 0)) {
AssertAlways(0 && "failed to create a pipe");
}
read_pipe_handle = (OS_Handle){ .u64[0] = (U64)read_pipe };
write_pipe_handle = (OS_Handle){ .u64[0] = (U64)write_pipe };
}
// Build Launch Options
OS_ProcessLaunchParams launch_opts = { .path = g_wdir, .inherit_env = 1, .stdout_file = output_redirect, .stderr_file = output_redirect };
str8_list_push(scratch.arena, &launch_opts.cmd_line, exe_path);
{
String8List parsed_cmdline = lnk_arg_list_parse_windows_rules(scratch.arena, cmdline);
str8_list_concat_in_place(&launch_opts.cmd_line, &parsed_cmdline);
}
OS_ProcessLaunchParams launch_opts = {
.path = g_wdir,
.inherit_env = 1,
.stdout_file = write_pipe_handle,
.stderr_file = write_pipe_handle,
.cmd_line = lnk_arg_list_parse_windows_rules(scratch.arena, cmdline),
};
str8_list_push_front(scratch.arena, &launch_opts.cmd_line, exe_path);
if (g_verbose) {
String8 full_cmd_line = str8_list_join(scratch.arena, &launch_opts.cmd_line, &(StringJoin){ .sep = str8_lit(" ") });
@@ -117,37 +165,54 @@ t_invoke(String8 exe_path, String8 cmdline, U64 timeout)
fprintf(stdout, "Working Dir: %.*s\n", str8_varg(g_wdir));
}
// Invoke Exe
int exit_code = -1;
{
OS_Handle process_handle = os_process_launch(&launch_opts);
if (!os_handle_match(process_handle, os_handle_zero())) {
U64 exit_code_u64 = 0;
is_ok = os_process_join(process_handle, timeout, &exit_code_u64);
exit_code = (int)exit_code_u64;
if (!is_ok) {
os_process_kill(process_handle);
// invoke exe
OS_Handle process_handle = os_process_launch(&launch_opts);
// close handle so last to ReadFile does not block
os_file_close(write_pipe_handle);
if ( ! os_handle_match(process_handle, os_handle_zero())) {
if (capture_output) {
// capture process output
String8List output = {0};
for (;;) {
String8 string = os_file_read_cstring(scratch.arena, read_pipe_handle, 0);
if (string.size == 0) { break; }
str8_list_push(scratch.arena, &output, string);
}
os_file_close(read_pipe_handle);
if (output_out) {
*output_out = str8_list_join(output_arena, &output, 0);
}
// write to the output file
if (g_redirect_stdout) {
os_write_data_list_to_file_path(g_stdout_file_name, output);
}
os_process_detach(process_handle);
}
}
// close handles
if (g_redirect_stdout) {
os_file_close(output_redirect);
}
U64 exit_code_u64 = 0;
if (os_process_join(process_handle, timeout, &exit_code_u64)) {
g_last_exit_code = (int)exit_code_u64;
is_ok = 1;
} else {
os_process_kill(process_handle);
}
// update global exit code
if (is_ok) {
g_last_exit_code = exit_code;
} else {
g_last_exit_code = -1;
os_process_detach(process_handle);
}
scratch_end(scratch);
return is_ok;
}
internal B32
t_invoke(String8 exe_path, String8 cmdline, U64 timeout)
{
return t_invoke_(exe_path, cmdline, timeout, 0, 0);
}
internal int
t_test_is_before(void *raw_a, void *raw_b)
{
+56 -2
View File
@@ -20,7 +20,7 @@ d2r_rdi_from_dwarf_writer(Arena *arena, DW_Writer *writer)
}
Assert(t_write_file(str8_lit("a.obj"), raw_coff));
t_invoke(str8_lit("radlink.exe"), str8_lit("/subsystem:console /out:a.exe /entry:main /DEBUG:FULL /opt:noref /opt:noicf a.obj"), max_U64);
t_invoke(t_radlink_path(), str8_lit("/subsystem:console /out:a.exe /entry:main /DEBUG:FULL /opt:noref /opt:noicf a.obj"), max_U64);
Assert(g_last_exit_code == 0);
String8 exe = t_read_file(scratch.arena, str8_lit("a.exe"));
Assert(exe.size > 0);
@@ -28,7 +28,7 @@ d2r_rdi_from_dwarf_writer(Arena *arena, DW_Writer *writer)
B32 was_pdb_deleted = os_delete_file_at_path(t_make_file_path(scratch.arena, str8_lit("a.pdb")));
Assert(was_pdb_deleted);
t_invoke(str8_lit("radbin.exe"), str8_lit("-rdi a.exe"), max_U64);
t_invoke_(t_radbin_path(), str8_lit("-rdi a.exe -out:a.rdi"), max_U64, 0, 0);
Assert(g_last_exit_code == 0);
String8 raw_rdi = t_read_file(arena, str8_lit("a.rdi"));
@@ -222,6 +222,60 @@ T_BeginTest(d2r_types)
}
T_EndTest;
#if 0
T_BeginTest(d2r_line_table)
{
DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64);
String8 comp_dir = str8_lit("c:/devel/");
String8 comp_name = str8_lit("test.c");
DW_WriterFile *file = dw_writer_new_file(writer, comp_name);
file->md5 = *(U128 *)&(U8[]){ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc };
struct {
DW_WriterFile *file; U64 ln; U64 line_size; U64 voff;
} test_table[] = {
{ file, 6, 1 },
{ file, 4, 2 },
{ file, 2, 3 },
{ file, 1, 4 },
{ file, 8, 5 },
};
U64 exe_base = coff_default_exe_base_from_machine(COFF_MachineType_X64);
U64 voff = 0x1000;
for EachElement(i, test_table) {
test_table[i].voff = voff;
dw_writer_line_emit(writer, test_table[i].file, test_table[i].ln, 0, exe_base + voff);
voff += test_table[i].line_size;
}
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
dw_writer_push_attrib_string(writer, DW_AttribKind_CompDir, comp_dir);
dw_writer_push_attrib_string(writer, DW_AttribKind_Name, comp_name);
dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, exe_base);
dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, exe_base + voff);
dw_writer_push_attrib_line_ptr(writer, DW_AttribKind_StmtList, 0);
dw_writer_tag_end(writer);
d2r_rdi_from_dwarf_writer(scratch.arena, writer);
for EachElement(i, test_table) {
for EachIndex(k, test_table[i].line_size) {
String8 cmd_line = str8f(scratch.arena, "-voff2line -voff:%llx, a.rdi", test_table[i].voff + k);
String8 output = {0};
t_invoke_(str8_lit("radbin.exe"), cmd_line, max_U64, scratch.arena, &output);
T_Ok(g_last_exit_code == 0);
T_MatchLinef(&output, "%S:/%llu", test_table[i].file->path, test_table[i].ln);
}
}
dw_writer_end(&writer);
}
T_EndTest;
#endif
T_BeginTest(d2r_general)
{
DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64);