mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-08 06:48:41 +00:00
improve error handling in the debugger harness (source file + line
number for error reports and allow scripts without header)
This commit is contained in:
committed by
Ryan Fleury
parent
56ee3bbf7b
commit
09afff7957
+51
-8
@@ -14,6 +14,7 @@ global String8 g_test_data;
|
||||
U64 g_torture_test_count;
|
||||
T_Test **g_torture_tests;
|
||||
T_Test g_torture_tests_[0xffffff];
|
||||
B32 g_is_first_print;
|
||||
|
||||
// invoke
|
||||
global U64 g_last_exit_code;
|
||||
@@ -159,21 +160,27 @@ internal void
|
||||
t_run_caller(void *raw_ctx)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
|
||||
g_is_first_print = 1;
|
||||
|
||||
T_RunCtx *ctx = raw_ctx;
|
||||
String8List test_out = {0};
|
||||
ctx->result.status = T_RunStatus_Pass;
|
||||
|
||||
String8List test_out = {0};
|
||||
ctx->run(scratch.arena, ctx->user_data, &ctx->result, &test_out);
|
||||
|
||||
if (ctx->result.status == T_RunStatus_Fail || ctx->result.status == T_RunStatus_Crash) {
|
||||
for EachNode(n, String8Node, test_out.first) {
|
||||
fprintf(stderr, "%.*s", str8_varg(n->string));
|
||||
t_errorf("%S", n->string);
|
||||
}
|
||||
if (g_errors.size) {
|
||||
fprintf(stderr, "stderr: \"%.*s\"\n", str8_varg(g_errors));
|
||||
t_errorf("stderr: \"%S\"\n", g_errors);
|
||||
}
|
||||
if (g_output.size) {
|
||||
fprintf(stderr, "stdout: \"%.*s\"\n", str8_varg(g_output));
|
||||
t_errorf("stdout: \"%S\"\n", g_output);
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
@@ -479,11 +486,7 @@ t_invoke_env(String8 exe_path, String8 cmdline, String8List env, U64 timeout_us)
|
||||
};
|
||||
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(" ") });
|
||||
fprintf(stdout, "Command Line: %.*s\n", str8_varg(full_cmd_line));
|
||||
fprintf(stdout, "Working Dir: %.*s\n", str8_varg(g_wdir));
|
||||
}
|
||||
|
||||
// invoke exe
|
||||
Process process_handle = process_launch(&launch_opts);
|
||||
@@ -757,6 +760,12 @@ t_invoke_env(String8 exe_path, String8 cmdline, String8List env, U64 timeout_us)
|
||||
}
|
||||
#endif
|
||||
|
||||
t_infof("Invoke: {\n");
|
||||
t_infof(" CMDL: %S\n", full_cmd_line);
|
||||
t_infof(" WDIR: %S\n", g_wdir);
|
||||
t_infof(" Exit: %u\n", g_last_exit_code);
|
||||
t_infof("}\n");
|
||||
|
||||
// update output global
|
||||
g_output = str8_list_join(g_output_arena, &stdout_parts, 0);
|
||||
g_errors = str8_list_join(g_output_arena, &stderr_parts, 0);
|
||||
@@ -971,6 +980,40 @@ t_match_folders(String8 a, String8 b)
|
||||
return is_match;
|
||||
}
|
||||
|
||||
internal void
|
||||
t_infof(char *fmt, ...)
|
||||
{
|
||||
if (g_verbose) {
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 result = push_str8fv(scratch.arena, fmt, args);
|
||||
if (g_is_first_print) {
|
||||
g_is_first_print = 0;
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
fprintf(stderr, "%.*s", str8_varg(result));
|
||||
va_end(args);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
t_errorf(char *fmt, ...)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 result = push_str8fv(scratch.arena, fmt, args);
|
||||
if (g_is_first_print) {
|
||||
g_is_first_print = 0;
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
fprintf(stderr, "%.*s", str8_varg(result));
|
||||
va_end(args);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
internal void
|
||||
t_entry_point(CmdLine *cmdline)
|
||||
{
|
||||
|
||||
+16
-2
@@ -101,7 +101,7 @@ internal void t_break_if_debugger_present(void);
|
||||
#define ENDT_MS(x) TIMEOUT_US((x)*1000ull)
|
||||
#define ENDT_SEC(x) TIMEOUT_MS((x)*1000ull)
|
||||
|
||||
////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// output directory
|
||||
internal B32 t_write_file_list(String8 name, String8List data);
|
||||
@@ -115,6 +115,7 @@ internal void t_run_caller(void *raw_ctx);
|
||||
internal void t_run_fail_handler(void *raw_ctx);
|
||||
internal T_RunResult t_run(T_Run run, String8 user_data);
|
||||
|
||||
// tools
|
||||
internal String8 t_radbin_path(void);
|
||||
internal String8 t_cl_path(void);
|
||||
internal String8 t_clang_path(void);
|
||||
@@ -128,7 +129,20 @@ internal B32 t_invoke_cl(char *fmt, ...);
|
||||
internal B32 t_invoke_linkerf(char *fmt, ...);
|
||||
internal B32 t_invoke_radbin(char *fmt, ...);
|
||||
internal void t_kill_all(String8 pattern);
|
||||
|
||||
#define t_invoke_linker_timeout(c, t) T_Ok(t_invoke(t_radlink_path(), c, t))
|
||||
#define t_invoke_linker_timeoutf(t, f, ...) t_invoke_linker_timeout(push_str8f(arena, f, ##__VA_ARGS__), t)
|
||||
#define t_invoke_linker(c) t_invoke_linker_timeout(c, max_U64)
|
||||
|
||||
internal void t_kill_all(String8 pattern);
|
||||
|
||||
internal String8 t_chop_line(String8 *string);
|
||||
internal B32 t_match_line(String8 *output, String8 expected_line);
|
||||
internal B32 t_match_linef(String8 *output, char *fmt, ...);
|
||||
|
||||
// files helper
|
||||
internal String8List t_file_paths_from_dir(Arena *arena, String8 dir);
|
||||
|
||||
// printer
|
||||
internal void t_infof(char *fmt, ...);
|
||||
internal void t_errorf(char *fmt, ...);
|
||||
|
||||
|
||||
+85
-54
@@ -86,15 +86,15 @@ t_dbg_status(T_DbgStatus *status_out, U64 timeout_us)
|
||||
if ( ! t_dbg_send_cmd(str8_lit("status"), timeout_us, scratch.arena, &reply)) { goto exit; }
|
||||
|
||||
// parse reply
|
||||
if ( ! rd_ipc_parse_b32(reply.msg, str8_lit("ok"), &is_ok)) { fprintf(stderr, "ERROR: failed to parse reply member: ok\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_b32(reply.msg, str8_lit("running"), &status.running)) { fprintf(stderr, "ERROR: failed to parse reply member: running\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_int(reply.msg, str8_lit("run_gen"), &status.run_gen)) { fprintf(stderr, "ERROR: failed to parse reply member: run_gen\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_int(reply.msg, str8_lit("ip"), &status.ip)) { fprintf(stderr, "ERROR: failed to parse reply member: ip\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_b32(reply.msg, str8_lit("ok"), &is_ok)) { t_errorf("ERROR: failed to parse reply member: ok\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_b32(reply.msg, str8_lit("running"), &status.running)) { t_errorf("ERROR: failed to parse reply member: running\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_int(reply.msg, str8_lit("run_gen"), &status.run_gen)) { t_errorf("ERROR: failed to parse reply member: run_gen\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_int(reply.msg, str8_lit("ip"), &status.ip)) { t_errorf("ERROR: failed to parse reply member: ip\n"); Assert(0); goto exit; }
|
||||
if (status_out != 0) { *status_out = status; }
|
||||
|
||||
exit:;
|
||||
if ( ! is_ok && reply.parse.root) {
|
||||
fprintf(stderr, "\tReply: %.*s\n", str8_varg(reply.parse.root->raw_string));
|
||||
t_errorf("\tReply: %S\n", reply.parse.root->raw_string);
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return is_ok;
|
||||
@@ -319,10 +319,10 @@ t_dbg_eval(Arena *arena, String8 expr, T_Eval *eval_out)
|
||||
B32 is_ok = t_dbg_send_cmd(cmd, T_Dbg_DefaultTimeout, arena, &reply);
|
||||
|
||||
T_Eval e = {0};
|
||||
if ( ! rd_ipc_parse_string(reply.msg, str8_lit("expr"), &e.expr)) { fprintf(stderr, "ERROR: failed to parse reply member: expr\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_string(reply.msg, str8_lit("value"), &e.value)) { fprintf(stderr, "ERROR: failed to parse reply member: value\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_string(reply.msg, str8_lit("type"), &e.type)) { fprintf(stderr, "ERROR: failed to parse reply member: type\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_string(reply.msg, str8_lit("error"), &e.error)) { fprintf(stderr, "ERROR: failed to parse reply member: error\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_string(reply.msg, str8_lit("expr"), &e.expr)) { t_errorf("ERROR: failed to parse reply member: expr\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_string(reply.msg, str8_lit("value"), &e.value)) { t_errorf("ERROR: failed to parse reply member: value\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_string(reply.msg, str8_lit("type"), &e.type)) { t_errorf("ERROR: failed to parse reply member: type\n"); Assert(0); goto exit; }
|
||||
if ( ! rd_ipc_parse_string(reply.msg, str8_lit("error"), &e.error)) { t_errorf("ERROR: failed to parse reply member: error\n"); Assert(0); goto exit; }
|
||||
if (eval_out) { *eval_out = e; }
|
||||
|
||||
exit:;
|
||||
@@ -346,29 +346,44 @@ t_dbg_script_program_is_before(void *raw_a, void *raw_b)
|
||||
return t_dbg_script_program_compar(raw_a, raw_b) < 0;
|
||||
}
|
||||
|
||||
internal String8
|
||||
t_string_from_dbg_script_cmd_kind(T_DbgScriptCmdKind v)
|
||||
{
|
||||
switch (v) {
|
||||
case T_DbgScriptCmdKind_Null: return str8_zero();
|
||||
case T_DbgScriptCmdKind_Breakpoint: return str8_lit("bp");
|
||||
case T_DbgScriptCmdKind_ClearBreakpoints: return str8_lit("bp_clear");
|
||||
case T_DbgScriptCmdKind_Run: return str8_lit("run");
|
||||
case T_DbgScriptCmdKind_Halt: return str8_lit("halt");
|
||||
case T_DbgScriptCmdKind_StepOver: return str8_lit("step_over");
|
||||
case T_DbgScriptCmdKind_StepInto: return str8_lit("step_into");
|
||||
case T_DbgScriptCmdKind_StepOut: return str8_lit("step_out");
|
||||
case T_DbgScriptCmdKind_StepOverInst: return str8_lit("step_over_inst");
|
||||
case T_DbgScriptCmdKind_StepIntoInst: return str8_lit("step_into_inst");
|
||||
case T_DbgScriptCmdKind_StepOverLine: return str8_lit("step_over_line");
|
||||
case T_DbgScriptCmdKind_StepIntoLine: return str8_lit("step_into_line");
|
||||
case T_DbgScriptCmdKind_KillAll: return str8_lit("kill_all");
|
||||
case T_DbgScriptCmdKind_At: return str8_lit("at");
|
||||
case T_DbgScriptCmdKind_Eval: return str8_lit("eval");
|
||||
default: InvalidPath;
|
||||
}
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal T_DbgScriptCmdKind
|
||||
t_dbg_script_cmd_kind_from_string(String8 cmd)
|
||||
{
|
||||
if (str8_matchi(cmd, str8_lit("bp"))) { return T_DbgScriptCmdKind_Breakpoint; }
|
||||
else if (str8_matchi(cmd, str8_lit("bp_clear"))) { return T_DbgScriptCmdKind_ClearBreakpoints; }
|
||||
else if (str8_matchi(cmd, str8_lit("run"))) { return T_DbgScriptCmdKind_Run; }
|
||||
else if (str8_matchi(cmd, str8_lit("halt"))) { return T_DbgScriptCmdKind_Halt; }
|
||||
else if (str8_matchi(cmd, str8_lit("step_over"))) { return T_DbgScriptCmdKind_StepOver; }
|
||||
else if (str8_matchi(cmd, str8_lit("step_into"))) { return T_DbgScriptCmdKind_StepInto; }
|
||||
else if (str8_matchi(cmd, str8_lit("step_out"))) { return T_DbgScriptCmdKind_StepOut; }
|
||||
else if (str8_matchi(cmd, str8_lit("step_over_inst"))) { return T_DbgScriptCmdKind_StepOverInst; }
|
||||
else if (str8_matchi(cmd, str8_lit("step_into_inst"))) { return T_DbgScriptCmdKind_StepIntoInst; }
|
||||
else if (str8_matchi(cmd, str8_lit("step_over_line"))) { return T_DbgScriptCmdKind_StepOverLine; }
|
||||
else if (str8_matchi(cmd, str8_lit("step_into_line"))) { return T_DbgScriptCmdKind_StepIntoLine; }
|
||||
else if (str8_matchi(cmd, str8_lit("at"))) { return T_DbgScriptCmdKind_At; }
|
||||
else if (str8_matchi(cmd, str8_lit("eval"))) { return T_DbgScriptCmdKind_Eval; }
|
||||
for EachIndex(i, T_DbgScriptCmdKind_Count) {
|
||||
if (str8_matchi(t_string_from_dbg_script_cmd_kind(i), cmd)) { return i; }
|
||||
}
|
||||
return T_DbgScriptCmdKind_Null;
|
||||
}
|
||||
|
||||
internal T_DbgScript
|
||||
t_dbg_script_from_source(Arena *arena, String8 file_path, String8 source)
|
||||
internal B32
|
||||
t_dbg_script_from_source(Arena *arena, String8 file_path, String8 source, T_DbgScript *script_out)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
B32 is_ok = 0;
|
||||
|
||||
T_DbgScript script = { .file_path = push_str8_copy(arena, file_path) };
|
||||
|
||||
@@ -409,10 +424,7 @@ t_dbg_script_from_source(Arena *arena, String8 file_path, String8 source)
|
||||
{
|
||||
MD_Node *test = script_parse.root->first;
|
||||
AssertAlways( ! md_node_is_nil(test));
|
||||
AssertAlways(str8_matchi(test->string, str8_lit("test")));
|
||||
|
||||
String8 os_name = string_from_operating_system(OperatingSystem_CURRENT);
|
||||
|
||||
if (str8_matchi(test->string, str8_lit("test"))) {
|
||||
for MD_EachNode(n, test->first) {
|
||||
OperatingSystem os = operating_system_from_string(n->string);
|
||||
AssertAlways(os != OperatingSystem_Null);
|
||||
@@ -447,6 +459,10 @@ t_dbg_script_from_source(Arena *arena, String8 file_path, String8 source)
|
||||
list->count += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t_errorf("ERROR: %S: missing test header\n", file_path);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
// file
|
||||
@@ -523,21 +539,20 @@ t_dbg_script_from_source(Arena *arena, String8 file_path, String8 source)
|
||||
p->file = file;
|
||||
hash_table_push_u64_raw(scratch.arena, ht, order, p);
|
||||
} else {
|
||||
fprintf(stderr, "ERROR: duplicate order number %llu found on line %llu\n", (unsigned long long)order, (unsigned long long)p->line);
|
||||
t_errorf("ERROR: duplicate order number %llu found on line %llu\n", (unsigned long long)order, (unsigned long long)p->line);
|
||||
}
|
||||
|
||||
MD_Node *cmd_name = n->first;
|
||||
MD_Node *cmd_arg = cmd_name->first;
|
||||
AssertAlways(!md_node_is_nil(cmd_name));
|
||||
|
||||
for MD_EachNode(cmd_n, n->first) {
|
||||
// push new cmd
|
||||
T_DbgScriptCmd *cmd = push_array(arena, T_DbgScriptCmd, 1);
|
||||
cmd->kind = t_dbg_script_cmd_kind_from_string(cmd_name->string);
|
||||
AssertAlways(cmd->kind != T_DbgScriptCmdKind_Null);
|
||||
SLLQueuePush(p->first, p->first, cmd);
|
||||
cmd->kind = t_dbg_script_cmd_kind_from_string(cmd_n->string);
|
||||
cmd->line = line;
|
||||
Assert(cmd->kind != T_DbgScriptCmdKind_Null);
|
||||
SLLQueuePush(p->first, p->last, cmd);
|
||||
p->count += 1;
|
||||
|
||||
// parse cmd args
|
||||
MD_Node *cmd_arg = cmd_n->first;
|
||||
if ( ! md_node_is_nil(cmd_arg)) {
|
||||
if (cmd->kind == T_DbgScriptCmdKind_At) {
|
||||
AssertAlways(try_s64_from_str8_c_rules(cmd_arg->string, &cmd->at.delta));
|
||||
@@ -549,14 +564,20 @@ t_dbg_script_from_source(Arena *arena, String8 file_path, String8 source)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
script.program_count = ht->count;
|
||||
script.programs = values_from_hash_table_raw(arena, ht);
|
||||
radsort(script.programs, script.program_count, t_dbg_script_program_is_before);
|
||||
}
|
||||
|
||||
is_ok = 1;
|
||||
exit:;
|
||||
if (script_out) {
|
||||
*script_out = script;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return script;
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
internal B32
|
||||
@@ -571,6 +592,8 @@ t_dbg_script_invoke(T_DbgScript *script, U64 timeout_us)
|
||||
|
||||
if (program->os == OperatingSystem_CURRENT) {
|
||||
for EachNode(cmd, T_DbgScriptCmd, program->first) {
|
||||
t_infof("[%llu] Command: %S:%llu %S\n", program->order, script->file_path, (unsigned long long)cmd->line, t_string_from_dbg_script_cmd_kind(cmd->kind));
|
||||
|
||||
switch (cmd->kind) {
|
||||
case T_DbgScriptCmdKind_Null: break;
|
||||
case T_DbgScriptCmdKind_Halt: t_dbg_send_cmd_and_wait_stop(str8_lit("halt"), timeout_us); break; // NOTE: does not auto-magically select main thread on stop
|
||||
@@ -597,7 +620,7 @@ t_dbg_script_invoke(T_DbgScript *script, U64 timeout_us)
|
||||
#else
|
||||
T_DbgStatus temp_status = {0};
|
||||
if ( ! t_dbg_status(&temp_status, T_Dbg_DefaultTimeout)) {
|
||||
fprintf(stderr, "ERROR: failed to query IP\n");
|
||||
t_errorf("ERROR: %S:%llu: failed to query IP\n", script->file_path, (unsigned long long)cmd->line);
|
||||
goto exit;
|
||||
}
|
||||
U64 ip = temp_status.ip;
|
||||
@@ -606,7 +629,7 @@ t_dbg_script_invoke(T_DbgScript *script, U64 timeout_us)
|
||||
// map IP -> source location
|
||||
T_DbgSourceLocation loc = {0};
|
||||
if (t_dbg_src_line(scratch.arena, ip, &loc, T_Dbg_DefaultTimeout) == 0) {
|
||||
fprintf(stderr, "ERROR: failed to map IP (0x%llx) to source location\n", (unsigned long long)ip);
|
||||
t_errorf("ERROR: %S:%llu: IP (0x%llx) does not map to a source line\n", script->file_path, (unsigned long long)cmd->line, (unsigned long long)ip);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@@ -619,11 +642,10 @@ t_dbg_script_invoke(T_DbgScript *script, U64 timeout_us)
|
||||
B32 mismatch = loc.pt.line != at_line_u64 ||
|
||||
!str8_match(loc.file_path, program->file->path, StringMatchFlag_CaseInsensitive|StringMatchFlag_SlashInsensitive);
|
||||
if (mismatch) {
|
||||
fprintf(stderr, "ERROR: location check did not pass:\n");
|
||||
fprintf(stderr, " Script : %.*s\n", str8_varg(script->file_path));
|
||||
fprintf(stderr, " Expected: %.*s:%llu\n", str8_varg(program->file->path), (unsigned long long)at_line_u64);
|
||||
fprintf(stderr, " Got : %.*s:%llu\n", str8_varg(loc.file_path), (unsigned long long)loc.pt.line);
|
||||
fprintf(stderr, " IP : 0x%llx\n", (unsigned long long)ip);
|
||||
t_errorf("ERROR: %S:%llu: location check did not pass:\n", script->file_path, (unsigned long long)cmd->line);
|
||||
t_errorf(" Expected: %S:%llu\n", program->file->path, (unsigned long long)at_line_u64);
|
||||
t_errorf(" Got : %S:%llu\n", loc.file_path, (unsigned long long)loc.pt.line);
|
||||
t_errorf(" IP : 0x%llx\n", (unsigned long long)ip);
|
||||
goto exit;
|
||||
}
|
||||
} break;
|
||||
@@ -645,24 +667,27 @@ internal
|
||||
T_RunSig(dbg_script_runner)
|
||||
{
|
||||
if ( ! file_path_exists(t_raddbg_path())) {
|
||||
fprintf(stderr, "ERROR: failed to find debugger \"%.*s\"\n", str8_varg(t_raddbg_path()));
|
||||
t_errorf("ERROR: failed to find debugger \"%S\"\n", t_raddbg_path());
|
||||
T_Ok(0);
|
||||
}
|
||||
|
||||
// read source file
|
||||
String8 source = data_from_file_path(arena, user_data);
|
||||
if (source.size == 0) {
|
||||
fprintf(stderr, "ERROR: failed to read script: \"%.*s\"\n", str8_varg(user_data));
|
||||
t_errorf("ERROR: failed to read script: \"%S\"\n", user_data);
|
||||
T_Ok(0);
|
||||
}
|
||||
|
||||
// source -> script
|
||||
T_DbgScript script = t_dbg_script_from_source(arena, user_data, source);
|
||||
T_DbgScript script = {0};
|
||||
if ( ! t_dbg_script_from_source(arena, user_data, source, &script)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// write source files to test folder
|
||||
for EachNode(file, T_DbgScriptFile, script.files.first) {
|
||||
if (write_data_to_file_path(file->path, file->source) == 0) {
|
||||
fprintf(stderr, "ERROR: %.*s:%llu: failed to write: \"%.*s\"\n", str8_varg(user_data), (unsigned long long)file->line, str8_varg(file->path));
|
||||
t_errorf("ERROR: %S:%llu: failed to write: \"%S\"\n", user_data, (unsigned long long)file->line, file->path);
|
||||
T_Ok(0);
|
||||
}
|
||||
}
|
||||
@@ -695,11 +720,11 @@ T_RunSig(dbg_script_runner)
|
||||
// invoke compiler with arguments from directive
|
||||
String8 expanded_args = lnk_expand_env_vars_windows(arena, script_vars, directive->args);
|
||||
if (t_invoke(compiler_path, expanded_args, max_U64) == 0) {
|
||||
fprintf(stderr, "ERROR: failed to launch compiler: \"%.*s %.*s\"\n", str8_varg(compiler_path), str8_varg(expanded_args));
|
||||
t_errorf("ERROR: failed to launch compiler: \"%S %S\"\n", compiler_path, expanded_args);
|
||||
T_Ok(0);
|
||||
}
|
||||
if (g_last_exit_code) {
|
||||
fprintf(stderr, "ERROR: %.*s\n", str8_varg(g_output));
|
||||
t_errorf("ERROR: %S:%llu: %S\n", script.file_path, (unsigned long long)directive->line, g_errors);
|
||||
if (g_stop_on_first_fail_or_crash) {
|
||||
T_Ok(0);
|
||||
}
|
||||
@@ -711,7 +736,11 @@ T_RunSig(dbg_script_runner)
|
||||
for EachNode(directive, T_DbgScriptDirective, script.directives[OperatingSystem_CURRENT][T_DbgScriptDirectiveKind_Link].first) {
|
||||
String8 expanded_args = lnk_expand_env_vars_windows(arena, script_vars, directive->args);
|
||||
if (t_invoke(linker_path, expanded_args, max_U64) == 0) {
|
||||
fprintf(stderr, "ERROR: failed to launch linker: \"%.*s %.*s\"\n", str8_varg(linker_path), str8_varg(expanded_args));
|
||||
t_errorf("ERROR: failed to launch linker: \"%S %S\"\n", linker_path, expanded_args);
|
||||
T_Ok(0);
|
||||
}
|
||||
if (g_last_exit_code != 0) {
|
||||
t_errorf("ERROR: %S:%llu: %S\n", script.file_path, (unsigned long long)directive->line, g_errors);
|
||||
T_Ok(0);
|
||||
}
|
||||
}
|
||||
@@ -721,14 +750,14 @@ T_RunSig(dbg_script_runner)
|
||||
String8 expanded_args = lnk_expand_env_vars_windows(arena, script_vars, directive->args);
|
||||
String8 cmdl = str8f(arena, "--user:%S.raddbg_user %S", t_make_file_path(arena, str8_lit("temp")), expanded_args);
|
||||
if (t_dbg_launch(cmdl, T_Dbg_DefaultTimeout) == 0) {
|
||||
fprintf(stderr, "ERROR: failed to launch debugger with command line \"%.*s %.*s\"; work dir \"%.*s\"\n", str8_varg(t_raddbg_path()), str8_varg(cmdl), str8_varg(g_wdir));
|
||||
t_errorf("ERROR: failed to launch debugger with command line \"%S %S\"; work dir \"%S\"\n", t_raddbg_path(), cmdl, g_wdir);
|
||||
T_Ok(0);
|
||||
}
|
||||
}
|
||||
|
||||
// debugger is ready -- now invoke script
|
||||
if (t_dbg_script_invoke(&script, T_Dbg_DefaultTimeout) == 0) {
|
||||
fprintf(stderr, "ERROR: %.*s: failed to run to completion\n", str8_varg(user_data));
|
||||
t_errrof("ERROR: %S: failed to run to completion\n", user_data);
|
||||
T_Ok(0);
|
||||
}
|
||||
|
||||
@@ -742,6 +771,8 @@ T_RunSig(dbg_script_runner)
|
||||
#else
|
||||
kill(g_dbg_pid, SIGKILL);
|
||||
#endif
|
||||
|
||||
exit:;
|
||||
g_dbg_pid = 0;
|
||||
}
|
||||
|
||||
@@ -751,7 +782,7 @@ t_dbg_register_script_tests(Arena *arena, String8 folder_path)
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
if ( ! folder_path_exists(folder_path)) {
|
||||
fprintf(stderr, "ERROR: this folder does not exists: %.*s\n", str8_varg(folder_path));
|
||||
t_errof("ERROR: this folder does not exists: %S\n", folder_path);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ typedef enum
|
||||
T_DbgScriptCmdKind_KillAll,
|
||||
T_DbgScriptCmdKind_At,
|
||||
T_DbgScriptCmdKind_Eval,
|
||||
T_DbgScriptCmdKind_Count
|
||||
} T_DbgScriptCmdKind;
|
||||
|
||||
typedef struct T_DbgScriptCmd
|
||||
@@ -107,6 +108,7 @@ typedef struct
|
||||
T_DbgScriptFileList files;
|
||||
U64 program_count;
|
||||
T_DbgScriptProgram **programs;
|
||||
B32 skip;
|
||||
} T_DbgScript;
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user