Skip to content

Commit e61dfd7

Browse files
committed
stdout redirection support in os command line launch helper; do rdi dumps in determinism test
1 parent 97abec1 commit e61dfd7

File tree

4 files changed

+128
-53
lines changed

4 files changed

+128
-53
lines changed

src/os/core/os_core.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,16 +163,52 @@ os_cmd_line_launch(String8 string)
163163
OS_Handle handle = {0};
164164
if(parts.node_count != 0)
165165
{
166+
// rjf: unpack exe part
166167
String8 exe = parts.first->string;
167168
String8 exe_folder = str8_chop_last_slash(exe);
168169
if(exe_folder.size == 0)
169170
{
170171
exe_folder = os_get_current_path(scratch.arena);
171172
}
173+
174+
// rjf: find stdout delimiter
175+
String8Node *stdout_delimiter_n = 0;
176+
for(String8Node *n = parts.first; n != 0; n = n->next)
177+
{
178+
if(str8_match(n->string, str8_lit(">"), 0))
179+
{
180+
stdout_delimiter_n = n;
181+
break;
182+
}
183+
}
184+
185+
// rjf: read stdout path
186+
String8 stdout_path = {0};
187+
if(stdout_delimiter_n && stdout_delimiter_n->next)
188+
{
189+
stdout_path = stdout_delimiter_n->next->string;
190+
}
191+
192+
// rjf: open stdout handle
193+
OS_Handle stdout_handle = {0};
194+
if(stdout_path.size != 0)
195+
{
196+
stdout_handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, stdout_path);
197+
}
198+
199+
// rjf: form command line
200+
String8List cmdline = {0};
201+
for(String8Node *n = parts.first; n != stdout_delimiter_n && n != 0; n = n->next)
202+
{
203+
str8_list_push(scratch.arena, &cmdline, n->string);
204+
}
205+
206+
// rjf: launch
172207
OS_ProcessLaunchParams params = {0};
173-
params.cmd_line = parts;
208+
params.cmd_line = cmdline;
174209
params.path = exe_folder;
175210
params.inherit_env = 1;
211+
params.stdout_file = stdout_handle;
176212
handle = os_process_launch(&params);
177213
}
178214
scratch_end(scratch);

src/os/core/os_core.h

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ enum
4444
OS_AccessFlag_Append = (1<<3),
4545
OS_AccessFlag_ShareRead = (1<<4),
4646
OS_AccessFlag_ShareWrite = (1<<5),
47+
OS_AccessFlag_Inherited = (1<<6),
4748
};
4849

4950
////////////////////////////////
@@ -79,19 +80,6 @@ struct OS_FileID
7980
U64 v[3];
8081
};
8182

82-
////////////////////////////////
83-
//~ rjf: Process Launch Parameters
84-
85-
typedef struct OS_ProcessLaunchParams OS_ProcessLaunchParams;
86-
struct OS_ProcessLaunchParams
87-
{
88-
String8List cmd_line;
89-
String8 path;
90-
String8List env;
91-
B32 inherit_env;
92-
B32 consoleless;
93-
};
94-
9583
////////////////////////////////
9684
//~ rjf: Handle Type
9785

@@ -123,6 +111,20 @@ struct OS_HandleArray
123111
U64 count;
124112
};
125113

114+
////////////////////////////////
115+
//~ rjf: Process Launch Parameters
116+
117+
typedef struct OS_ProcessLaunchParams OS_ProcessLaunchParams;
118+
struct OS_ProcessLaunchParams
119+
{
120+
String8List cmd_line;
121+
String8 path;
122+
String8List env;
123+
B32 inherit_env;
124+
B32 consoleless;
125+
OS_Handle stdout_file;
126+
};
127+
126128
////////////////////////////////
127129
//~ rjf: Globally Unique IDs
128130

src/os/core/win32/os_core_win32.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,14 +293,19 @@ os_file_open(OS_AccessFlags flags, String8 path)
293293
DWORD access_flags = 0;
294294
DWORD share_mode = 0;
295295
DWORD creation_disposition = OPEN_EXISTING;
296+
SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), 0, 0};
296297
if(flags & OS_AccessFlag_Read) {access_flags |= GENERIC_READ;}
297298
if(flags & OS_AccessFlag_Write) {access_flags |= GENERIC_WRITE;}
298299
if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;}
299300
if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;}
300301
if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;}
301302
if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;}
302-
if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS;}
303-
HANDLE file = CreateFileW((WCHAR *)path16.str, access_flags, share_mode, 0, creation_disposition, FILE_ATTRIBUTE_NORMAL, 0);
303+
if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS; access_flags |= FILE_APPEND_DATA; }
304+
if(flags & OS_AccessFlag_Inherited)
305+
{
306+
security_attributes.bInheritHandle = 1;
307+
}
308+
HANDLE file = CreateFileW((WCHAR *)path16.str, access_flags, share_mode, &security_attributes, creation_disposition, FILE_ATTRIBUTE_NORMAL, 0);
304309
if(file != INVALID_HANDLE_VALUE)
305310
{
306311
result.u64[0] = (U64)file;
@@ -926,9 +931,17 @@ os_process_launch(OS_ProcessLaunchParams *params)
926931
}
927932

928933
//- rjf: launch
934+
BOOL inherit_handles = 0;
929935
STARTUPINFOW startup_info = {sizeof(startup_info)};
936+
if(!os_handle_match(params->stdout_file, os_handle_zero()))
937+
{
938+
HANDLE stdout_handle = (HANDLE)params->stdout_file.u64[0];
939+
startup_info.hStdOutput = stdout_handle;
940+
startup_info.dwFlags |= STARTF_USESTDHANDLES;
941+
inherit_handles = 1;
942+
}
930943
PROCESS_INFORMATION process_info = {0};
931-
if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 0, creation_flags, use_null_env_arg ? 0 : (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info))
944+
if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, inherit_handles, creation_flags, use_null_env_arg ? 0 : (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info))
932945
{
933946
result.u64[0] = (U64)process_info.hProcess;
934947
CloseHandle(process_info.hThread);

src/tester/tester_main.c

Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -44,67 +44,91 @@ entry_point(CmdLine *cmdline)
4444
B32 good = 1;
4545
String8List out = {0};
4646
{
47-
name = str8_lit("PDB -> RDI determinism");
48-
OS_HandleList processes = {0};
49-
String8List rdi_paths = {0};
47+
name = str8_lit("pdb2rdi_determinism");
5048
U64 num_repeats_per_pdb = 4;
5149
String8 pdb_paths[] =
5250
{
5351
str8_lit_comp("odintest/test.pdb"),
52+
str8_lit_comp("mule_main.pdb"),
5453
};
5554
for EachElement(pdb_idx, pdb_paths)
5655
{
56+
// rjf: unpack paths, make output directory
5757
String8 pdb_path = path_normalized_from_string(arena, pdb_paths[pdb_idx]);
5858
String8 pdb_folder = str8_chop_last_slash(pdb_path);
59-
String8 repeat_folder = push_str8f(arena, "%S/pdb2rdi_determinism", pdb_folder);
59+
String8 repeat_folder = push_str8f(arena, "%S/%S", pdb_folder, name);
6060
os_make_directory(repeat_folder);
61-
for EachIndex(repeat_idx, num_repeats_per_pdb)
61+
62+
// rjf: generate all RDIs
63+
String8List rdi_paths = {0};
6264
{
63-
String8 rdi_path = push_str8f(arena, "%S/repeat_%I64u.rdi", repeat_folder, repeat_idx);
64-
str8_list_push(arena, &rdi_paths, rdi_path);
65-
os_handle_list_push(arena, &processes, os_cmd_line_launchf("rdi_from_pdb --pdb:%S --out:%S", pdb_path, rdi_path));
65+
OS_HandleList processes = {0};
66+
for EachIndex(repeat_idx, num_repeats_per_pdb)
67+
{
68+
String8 rdi_path = push_str8f(arena, "%S/repeat_%I64u.rdi", repeat_folder, repeat_idx);
69+
str8_list_push(arena, &rdi_paths, rdi_path);
70+
os_handle_list_push(arena, &processes, os_cmd_line_launchf("rdi_from_pdb --pdb:%S --out:%S", pdb_path, rdi_path));
71+
}
72+
for(OS_HandleNode *n = processes.first; n != 0; n = n->next)
73+
{
74+
os_process_join(n->v, max_U64);
75+
}
6676
}
67-
};
68-
for(OS_HandleNode *n = processes.first; n != 0; n = n->next)
69-
{
70-
os_process_join(n->v, max_U64);
71-
}
72-
U64 hashes_count = rdi_paths.node_count;
73-
U128 *hashes = push_array(arena, U128, hashes_count);
74-
String8 *paths = push_array(arena, String8, hashes_count);
75-
{
76-
U64 idx = 0;
77-
for(String8Node *n = rdi_paths.first; n != 0; n = n->next, idx += 1)
77+
78+
// rjf: generate all dumps
7879
{
79-
String8 path = n->string;
80-
String8 data = os_data_from_file_path(arena, path);
81-
hashes[idx] = hs_hash_from_data(data);
82-
paths[idx] = path;
80+
OS_HandleList processes = {0};
81+
for(String8Node *n = rdi_paths.first; n != 0; n = n->next)
82+
{
83+
String8 rdi_path = n->string;
84+
String8 dump_path = push_str8f(arena, "%S.dump", rdi_path);
85+
os_handle_list_push(arena, &processes, os_cmd_line_launchf("rdi_dump %S > %S", rdi_path, dump_path));
86+
}
8387
}
84-
}
85-
B32 matches = 1;
86-
for EachIndex(idx, hashes_count)
87-
{
88-
if(!u128_match(hashes[idx], hashes[0]))
88+
89+
// rjf: gather all hashes/paths
90+
U64 hashes_count = rdi_paths.node_count;
91+
U128 *hashes = push_array(arena, U128, hashes_count);
92+
String8 *paths = push_array(arena, String8, hashes_count);
8993
{
90-
matches = 0;
91-
break;
94+
U64 idx = 0;
95+
for(String8Node *n = rdi_paths.first; n != 0; n = n->next, idx += 1)
96+
{
97+
String8 path = n->string;
98+
String8 data = os_data_from_file_path(arena, path);
99+
hashes[idx] = hs_hash_from_data(data);
100+
paths[idx] = path;
101+
}
92102
}
93-
}
94-
if(!matches)
95-
{
96-
good = 0;
103+
104+
// rjf: determine if all hashes match
105+
B32 matches = 1;
97106
for EachIndex(idx, hashes_count)
98107
{
99-
str8_list_pushf(arena, &out, " [%I64u] (%S): 0x%I64x:%I64x\n", idx, paths[idx], hashes[idx].u64[0], hashes[idx].u64[1]);
108+
if(!u128_match(hashes[idx], hashes[0]))
109+
{
110+
matches = 0;
111+
break;
112+
}
113+
}
114+
115+
// rjf: output bad case info
116+
if(!matches)
117+
{
118+
good = 0;
119+
str8_list_pushf(arena, &out, " pdb[%I64u] \"%S\"\n", pdb_idx, pdb_path);
120+
for EachIndex(idx, hashes_count)
121+
{
122+
str8_list_pushf(arena, &out, " rdi[%I64u] \"%S\": 0x%I64x:%I64x\n", idx, paths[idx], hashes[idx].u64[0], hashes[idx].u64[1]);
123+
}
100124
}
101125
}
102126
}
103127

104128
//////////////////////////////
105129
//- rjf: dump results
106130
//
107-
fprintf(stderr, "[%s] %.*s\n", good ? "." : "X", str8_varg(name));
131+
fprintf(stderr, "[%s] \"%.*s\"\n", good ? "." : "X", str8_varg(name));
108132
if(!good)
109133
{
110134
for(String8Node *n = out.first; n != 0; n = n->next)

0 commit comments

Comments
 (0)