mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-08 23:08:08 +00:00
port pdb -> rdi determinism test
This commit is contained in:
@@ -53,8 +53,19 @@ jobs:
|
||||
- name: run-torture
|
||||
shell: cmd
|
||||
run: |
|
||||
rem find path to clang
|
||||
for /f "tokens=*" %%i in ('where clang') do set clang_path=%%~dpi
|
||||
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
|
||||
call build asan meta torture radlink radbin "${{matrix.mode}}" "${{matrix.compiler}}" || exit /b 1
|
||||
|
||||
rem set clang path before MSVC's clang path
|
||||
set PATH=%clang_path%;%PATH%
|
||||
|
||||
rem parse out clang version number out of --version to build path to the folder with ASAN DLL
|
||||
for /f "tokens=3 delims=. " %%v in ('clang -v 2^>^&1 ^| findstr version') do set clang_version=%%v
|
||||
if "${{matrix.compiler}}" == "clang" set PATH=%clang_path%..\lib\clang\%clang_version%\lib\windows;%PATH%
|
||||
|
||||
call build asan meta torture radlink radbin mule_main mule_module "${{matrix.mode}}" "${{matrix.compiler}}" || exit /b 1
|
||||
cd build
|
||||
torture || exit /b 1
|
||||
|
||||
|
||||
@@ -82,7 +82,6 @@ set clang_out= -o
|
||||
set clang_linker= -Xlinker
|
||||
|
||||
:: --- Per-Build Settings -----------------------------------------------------
|
||||
set link_dll=-DLL
|
||||
set link_icon=logo.res
|
||||
if "%msvc%"=="1" set linker=%cl_linker%
|
||||
if "%clang%"=="1" set linker=%clang_linker%
|
||||
@@ -94,6 +93,8 @@ if "%msvc%"=="1" set no_aslr=/DYNAMICBASE:NO
|
||||
if "%clang%"=="1" set no_aslr=-Wl,/DYNAMICBASE:NO
|
||||
if "%msvc%"=="1" set rc=call rc
|
||||
if "%clang%"=="1" set rc=call llvm-rc
|
||||
if "%msvc%"=="1" set link_dll=/link /DLL
|
||||
if "%clang%"=="1" set link_dll=-Xlinker -DLL
|
||||
|
||||
:: --- Choose Compile/Link Lines ----------------------------------------------
|
||||
if "%msvc%"=="1" set compile_debug=%cl_debug%
|
||||
@@ -147,7 +148,7 @@ if "%debugstringperf%"=="1" set didbuild=1 && %compile% ..\src\scratc
|
||||
if "%parse_inline_sites%"=="1" set didbuild=1 && %compile% ..\src\scratch\parse_inline_sites.c %compile_link% %out%parse_inline_sites.exe || exit /b 1
|
||||
if "%strip_lib_debug%"=="1" set didbuild=1 && %compile% ..\src\strip_lib_debug\strip_lib_debug.c %compile_link% %out%strip_lib_debug.exe || exit /b 1
|
||||
if "%mule_main%"=="1" set didbuild=1 && del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp %out%mule_inline.obj && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp %out%mule_o2.obj && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1
|
||||
if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1
|
||||
if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %link_dll% %out%mule_module.dll || exit /b 1
|
||||
if "%mule_hotload%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1
|
||||
if "%torture%"=="1" set didbuild=1 && %compile% ..\src\torture\torture_main.c %compile_link% %out%torture.exe || exit /b1
|
||||
if "%dwarf_expr_test%"=="1" set didbuild=1 && %compile% ..\src\torture\dwarf_expr_test.c %compile_link% %out%dwarf_expr_test.exe || exit /b1
|
||||
|
||||
+5
-2
@@ -1253,13 +1253,16 @@ rb_thread_entry_point(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: dump input files in order
|
||||
//- rjf: dump input files in ordere
|
||||
for(RB_FileNode *n = input_files.first; n != 0; n = n->next)
|
||||
{
|
||||
RB_File *f = n->v;
|
||||
if(lane_idx() == 0)
|
||||
{
|
||||
str8_list_pushf(arena, &output_blobs, "// %S (%S)\n\n", deterministic ? str8_skip_last_slash(f->path) : f->path, f->format ? rb_file_format_display_name_table[f->format] : str8_lit("Unsupported format"));
|
||||
if(!deterministic)
|
||||
{
|
||||
str8_list_pushf(arena, &output_blobs, "// %S (%S)\n\n", f->path, f->format ? rb_file_format_display_name_table[f->format] : str8_lit("Unsupported format"));
|
||||
}
|
||||
}
|
||||
lane_sync();
|
||||
|
||||
|
||||
+62
-5
@@ -9,6 +9,7 @@ global B32 g_verbose;
|
||||
global B32 g_redirect_stdout = 1;
|
||||
global B32 g_stop_on_first_fail_or_crash = 1;
|
||||
global String8 g_linker;
|
||||
global String8 g_test_data;
|
||||
|
||||
// tests
|
||||
U64 g_torture_test_count;
|
||||
@@ -76,13 +77,28 @@ t_make_file_path(Arena *arena, String8 name)
|
||||
return push_str8f(arena, "%S\\%S", g_wdir, name);
|
||||
}
|
||||
|
||||
internal B32
|
||||
t_make_dir(String8 name)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
B32 is_ok = os_make_directory(t_make_file_path(scratch.arena, name));
|
||||
scratch_end(scratch);
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
internal void
|
||||
t_run_caller(void *raw_ctx)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
T_RunCtx *ctx = raw_ctx;
|
||||
String8List test_out = {0};
|
||||
ctx->result.status = T_RunStatus_Pass;
|
||||
ctx->run(scratch.arena, &ctx->result);
|
||||
ctx->run(scratch.arena, &ctx->result, &test_out);
|
||||
if (ctx->result.status == T_RunStatus_Fail) {
|
||||
for EachNode(n, String8Node, test_out.first) {
|
||||
fprintf(stderr, "%.*s", str8_varg(n->string));
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
@@ -131,7 +147,9 @@ t_cl_path(void)
|
||||
ArenaParams params = { .reserve_size = sizeof(buffer), .commit_size = sizeof(buffer), .optional_backing_buffer = buffer };
|
||||
Arena *arena = arena_alloc_(¶ms);
|
||||
#if OS_WINDOWS
|
||||
path = str8_lit("cl.exe");
|
||||
wchar_t full_cl_path[MAX_PATH];
|
||||
DWORD full_cl_path_size = SearchPathW(0, L"cl.exe", 0, ArrayCount(full_cl_path), full_cl_path, 0);
|
||||
path = str8_from_16(arena, str16((U16*)full_cl_path, full_cl_path_size));
|
||||
#else
|
||||
path = str8_lit("cl");
|
||||
#endif
|
||||
@@ -159,14 +177,14 @@ t_radlink_path(void)
|
||||
}
|
||||
|
||||
internal String8
|
||||
t_src_path(void)
|
||||
t_cwd_path(void)
|
||||
{
|
||||
local_persist U8 path[4096] = {0};
|
||||
if (path[0] == 0) {
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 cwd = os_get_current_path(scratch.arena);
|
||||
cwd = str8_chop_last_slash(cwd);
|
||||
cwd = str8f(scratch.arena, "%S/src", cwd);
|
||||
cwd = str8f(scratch.arena, "%S", cwd);
|
||||
MemoryCopyStr8(path, cwd);
|
||||
path[cwd.size] = 0;
|
||||
scratch_end(scratch);
|
||||
@@ -174,8 +192,22 @@ t_src_path(void)
|
||||
return str8_cstring_capped(path, path+sizeof(path));
|
||||
}
|
||||
|
||||
internal String8
|
||||
t_src_path(void)
|
||||
{
|
||||
local_persist U8 path[4096] = {0};
|
||||
if (path[0] == 0) {
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 src = str8f(scratch.arena, "%S/src", t_cwd_path());
|
||||
MemoryCopyStr8(path, src);
|
||||
path[src.size] = 0;
|
||||
scratch_end(scratch);
|
||||
}
|
||||
return str8_cstring_capped(path, path+sizeof(path));
|
||||
}
|
||||
|
||||
internal B32
|
||||
t_invoke_(String8 exe_path, String8 cmdline, U64 timeout, Arena *output_arena, String8 *output_out)
|
||||
t_invoke_env(String8 exe_path, String8 cmdline, String8List env, U64 timeout, Arena *output_arena, String8 *output_out)
|
||||
{
|
||||
Temp scratch = scratch_begin(&output_arena,1);
|
||||
|
||||
@@ -200,6 +232,7 @@ t_invoke_(String8 exe_path, String8 cmdline, U64 timeout, Arena *output_arena, S
|
||||
OS_ProcessLaunchParams launch_opts = {
|
||||
.path = g_wdir,
|
||||
.inherit_env = 1,
|
||||
.env = env,
|
||||
.stdout_file = write_pipe_handle,
|
||||
.stderr_file = write_pipe_handle,
|
||||
.cmd_line = lnk_arg_list_parse_windows_rules(scratch.arena, cmdline),
|
||||
@@ -252,6 +285,12 @@ t_invoke_(String8 exe_path, String8 cmdline, U64 timeout, Arena *output_arena, S
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
internal B32
|
||||
t_invoke_(String8 exe_path, String8 cmdline, U64 timeout, Arena *output_arena, String8 *output_out)
|
||||
{
|
||||
return t_invoke_env(exe_path, cmdline, (String8List){0}, timeout, output_arena, output_out);
|
||||
}
|
||||
|
||||
internal B32
|
||||
t_invoke(String8 exe_path, String8 cmdline, U64 timeout)
|
||||
{
|
||||
@@ -368,6 +407,17 @@ t_entry_point(CmdLine *cmdline)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle -test_data
|
||||
//
|
||||
{
|
||||
g_test_data = cmd_line_string(cmdline, str8_lit("test_data"));
|
||||
if (g_test_data.size == 0) {
|
||||
g_test_data = str8f(scratch.arena, "%S/build", t_cwd_path());
|
||||
//fprintf(stderr, "WARNING: The test data folder path was not specified. Specify the path when running the program, assuming: %.*s --test_data:%.*s\n", str8_varg(cmdline->exe_name), str8_varg(g_test_data));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle optional -target
|
||||
//
|
||||
@@ -390,6 +440,13 @@ t_entry_point(CmdLine *cmdline)
|
||||
g_redirect_stdout = !cmd_line_has_flag(cmdline, str8_lit("print_stdout"));
|
||||
g_stop_on_first_fail_or_crash = !cmd_line_has_flag(cmdline, str8_lit("keep_going"));
|
||||
|
||||
// default options when running under debugger
|
||||
#if OS_WINDOWS
|
||||
if (!cmd_line_has_flag(cmdline, str8_lit("print_stdout")) && IsDebuggerPresent()) {
|
||||
g_redirect_stdout = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle -out
|
||||
{
|
||||
CmdLineOpt *out_opt = cmd_line_opt_from_string(cmdline, str8_lit("out"));
|
||||
|
||||
@@ -20,8 +20,8 @@ typedef struct
|
||||
char *fail_cond;
|
||||
} T_RunResult;
|
||||
|
||||
#define T_RunSig(name) void t_##name(Arena *arena, T_RunResult *result_out)
|
||||
typedef void (*T_Run)(Arena *arena, T_RunResult *result_out);
|
||||
#define T_RunSig(name) void t_##name(Arena *arena, T_RunResult *result_out, String8List *test_out)
|
||||
typedef void (*T_Run)(Arena *arena, T_RunResult *result_out, String8List *test_out);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -63,6 +63,7 @@ extern T_Test g_torture_tests[0xffffff];
|
||||
|
||||
#define T_Ok(c) do { if (!(c)) { result_out->fail_file = __FILE__; result_out->fail_line = __LINE__; result_out->fail_cond = Stringify(c); result_out->status = T_RunStatus_Fail; return; } } while(0)
|
||||
#define T_MatchLinef(out, ...) T_Ok(t_match_linef(out, __VA_ARGS__))
|
||||
#define t_outf(...) str8_list_pushf(arena, test_out, ## __VA_ARGS__)
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -81,6 +82,7 @@ internal T_RunResult t_run(T_Run run);
|
||||
internal String8 t_radbin_path(void);
|
||||
internal String8 t_cl_path(void);
|
||||
internal String8 t_radlink_path(void);
|
||||
internal String8 t_cwd_path(void);
|
||||
internal String8 t_src_path(void);
|
||||
|
||||
internal B32 t_invoke(String8 exe, String8 cmdline, U64 timeout);
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
#include "torture_radlink.c"
|
||||
#include "torture_dwarf.c"
|
||||
#include "torture_d2r.c"
|
||||
#include "torture_p2r.c"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
#define T_Group "p2r"
|
||||
|
||||
#if OS_WINDOWS
|
||||
T_BeginTest(p2r_determ)
|
||||
{
|
||||
U64 num_repeats_per_pdb = 32;
|
||||
String8 pdb_paths[] =
|
||||
{
|
||||
push_str8f(arena, "%S/mule_main.pdb", g_test_data),
|
||||
push_str8f(arena, "%S/mule_module.pdb", g_test_data),
|
||||
};
|
||||
for EachElement(pdb_idx, pdb_paths)
|
||||
{
|
||||
// rjf: unpack paths, make output directory
|
||||
String8 pdb_path = path_normalized_from_string(arena, pdb_paths[pdb_idx]);
|
||||
|
||||
// rjf: generate all RDIs
|
||||
String8List rdi_paths = {0};
|
||||
String8List dump_paths = {0};
|
||||
{
|
||||
OS_HandleList processes = {0};
|
||||
for EachIndex(repeat_idx, num_repeats_per_pdb)
|
||||
{
|
||||
String8 rdi_name = push_str8f(arena, "repeat_%I64u.rdi", repeat_idx);
|
||||
String8 rdi_path = t_make_file_path(arena, rdi_name);
|
||||
str8_list_push(arena, &rdi_paths, rdi_path);
|
||||
String8 cmdl = str8f(arena, "radbin -rdi -deterministic %S -out:%S", pdb_path, rdi_path);
|
||||
OS_Handle process_handle = os_cmd_line_launch(cmdl);
|
||||
T_Ok(!os_handle_match(os_handle_zero(), process_handle));
|
||||
os_handle_list_push(arena, &processes, process_handle);
|
||||
}
|
||||
|
||||
// wait on the converters
|
||||
for EachNode(n, OS_HandleNode, processes.first) { os_process_join(n->v, max_U64, 0); }
|
||||
}
|
||||
|
||||
// rjf: generate all dumps
|
||||
{
|
||||
OS_HandleList processes = {0};
|
||||
for EachNode(n, String8Node, rdi_paths.first)
|
||||
{
|
||||
String8 rdi_path = n->string;
|
||||
String8 dump_path = push_str8f(arena, "%S.dump", rdi_path);
|
||||
str8_list_push(arena, &dump_paths, dump_path);
|
||||
OS_Handle process_handle = os_cmd_line_launchf("radbin -dump -deterministic %S -out:%S", rdi_path, dump_path);
|
||||
T_Ok(!os_handle_match(os_handle_zero(), process_handle));
|
||||
os_handle_list_push(arena, &processes, process_handle);
|
||||
}
|
||||
for EachNode(n, OS_HandleNode, processes.first) { os_process_join(n->v, max_U64, 0); }
|
||||
}
|
||||
|
||||
// rjf: gather all hashes/paths
|
||||
U64 rdi_hashes_count = rdi_paths.node_count;
|
||||
U128 *rdi_hashes = push_array(arena, U128, rdi_hashes_count);
|
||||
String8 *rdi_paths_array = push_array(arena, String8, rdi_hashes_count);
|
||||
U64 dump_hashes_count = dump_paths.node_count;
|
||||
U128 *dump_hashes = push_array(arena, U128, dump_hashes_count);
|
||||
String8 *dump_paths_array = push_array(arena, String8, dump_hashes_count);
|
||||
{
|
||||
U64 idx = 0;
|
||||
for EachNode(n, String8Node, rdi_paths.first)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 rdi_path = n->string;
|
||||
String8 path = rdi_path;
|
||||
T_Ok(path.size);
|
||||
String8 data = os_data_from_file_path(scratch.arena, path);
|
||||
T_Ok(data.size);
|
||||
rdi_hashes [idx] = u128_hash_from_str8(data);
|
||||
rdi_paths_array[idx] = path;
|
||||
scratch_end(scratch);
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
U64 idx = 0;
|
||||
for EachNode(n, String8Node, dump_paths.first)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 path = n->string;
|
||||
T_Ok(path.size);
|
||||
String8 data = os_data_from_file_path(scratch.arena, path);
|
||||
T_Ok(data.size);
|
||||
dump_hashes [idx] = u128_hash_from_str8(data);
|
||||
dump_paths_array[idx] = path;
|
||||
scratch_end(scratch);
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: determine if all hashes match
|
||||
U64 mismatch_idx = max_U64;
|
||||
for EachIndex(idx, rdi_hashes_count)
|
||||
{
|
||||
if(!u128_match(rdi_hashes[idx], rdi_hashes[0]))
|
||||
{
|
||||
mismatch_idx = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for EachIndex(idx, dump_hashes_count)
|
||||
{
|
||||
if(!u128_match(dump_hashes[idx], dump_hashes[0]))
|
||||
{
|
||||
mismatch_idx = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: output bad case info
|
||||
if (mismatch_idx != max_U64) {
|
||||
U64 idx = mismatch_idx;
|
||||
t_outf(" pdb[%I64u] \"%S\"\n", idx, pdb_path);
|
||||
t_outf(" rdi[%I64u] 0x%I64x:%I64x \"%S\"\n", idx, rdi_hashes[idx].u64[0], rdi_hashes[idx].u64[1], rdi_paths_array[idx]);
|
||||
t_outf(" dump[%I64u] 0x%I64x:%I64x \"%S\"\n", idx, dump_hashes[idx].u64[0], dump_hashes[idx].u64[1], dump_paths_array[idx]);
|
||||
T_Ok(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef T_Group
|
||||
|
||||
@@ -4773,10 +4773,11 @@ t_radlink_validate_asan_out(String8 obj_name)
|
||||
|
||||
String8 exe_path = t_make_file_path(scratch.arena, str8f(scratch.arena, "%S.exe", str8_chop_last_dot(obj_name)));
|
||||
String8 out = {0};
|
||||
t_invoke_(exe_path, str8_zero(), max_U64, scratch.arena, &out);
|
||||
if (g_last_exit_code == 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
char *old_path_cstr = getenv("PATH");
|
||||
String8List env = {0};
|
||||
str8_list_pushf(scratch.arena, &env, "PATH=%S;%S", str8_chop_last_slash(t_cl_path()), str8_cstring(old_path_cstr));
|
||||
t_invoke_env(exe_path, str8_zero(), env, max_U64, scratch.arena, &out);
|
||||
|
||||
String8 s = out;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user