log: fix log issue which hurt console badly

This commit is contained in:
David Gonzalez Martin 2023-07-14 09:56:05 -06:00
parent 820e60a506
commit 2500b78896
10 changed files with 97 additions and 37 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ bochsout.txt
*.hdd
loopback_device
tools/OVMF.fd
logs/*.log

View File

@ -467,6 +467,8 @@ pub fn build(b_arg: *Build) !void {
const user_init = user_module_list.items[0];
const is_default = architecture == default_configuration.architecture and bootloader == default_configuration.bootloader and boot_protocol == default_configuration.boot_protocol and optimize_mode == default_configuration.optimize_mode and execution_environment == default_configuration.execution_environment and execution_type == default_configuration.execution_type;
const runner_run = try newRunnerRunArtifact(.{
.configuration = configuration,
.disk_image_path = disk_image_path,
@ -479,7 +481,9 @@ pub fn build(b_arg: *Build) !void {
.is_test = is_test,
},
.ovmf_path = ovmf_path,
.is_default = is_default,
});
const runner_debug = try newRunnerRunArtifact(.{
.configuration = configuration,
.disk_image_path = disk_image_path,
@ -492,13 +496,14 @@ pub fn build(b_arg: *Build) !void {
.is_test = is_test,
},
.ovmf_path = ovmf_path,
.is_default = is_default,
});
if (is_test) {
build_steps.test_all.dependOn(&runner_run.step);
}
if (architecture == default_configuration.architecture and bootloader == default_configuration.bootloader and boot_protocol == default_configuration.boot_protocol and optimize_mode == default_configuration.optimize_mode and execution_environment == default_configuration.execution_environment and execution_type == default_configuration.execution_type) {
if (is_default) {
if (is_test) {
build_steps.test_run.dependOn(&runner_run.step);
build_steps.test_debug.dependOn(&runner_debug.step);
@ -592,6 +597,7 @@ fn newRunnerRunArtifact(arguments: struct {
user_init: *CompileStep,
qemu_options: QEMUOptions,
ovmf_path: FileSource,
is_default: bool,
}) !*RunStep {
const runner = b.addRunArtifact(arguments.runner);
@ -609,6 +615,7 @@ fn newRunnerRunArtifact(arguments: struct {
.debug_user => runner.addArg(if (debug_user) "true" else "false"),
.debug_loader => runner.addArg(if (debug_loader) "true" else "false"),
.ovmf_path => runner.addFileSourceArg(arguments.ovmf_path),
.is_default => runner.addArg(if (arguments.is_default) "true" else "false"),
};
return runner;

View File

@ -1,6 +1,6 @@
{
"architecture": "x86_64",
"bootloader": "birth",
"bootloader": "limine",
"boot_protocol": "uefi",
"execution_environment": "qemu",
"optimize_mode": "Debug",

View File

@ -8,7 +8,6 @@
"smp": 2,
"debugcon": "stdio",
"log": {
"file": null,
"guest_errors": true,
"assembly": false,
"interrupts": true

0
logs/.gitkeep Normal file
View File

View File

@ -481,6 +481,7 @@ pub const ArgumentParser = struct {
debug_loader,
init,
ovmf_path,
is_default,
};
pub const Result = struct {
@ -495,6 +496,7 @@ pub const ArgumentParser = struct {
debug_loader: bool,
init: []const u8,
ovmf_path: []const u8,
is_default: bool,
};
};
};

View File

@ -57,6 +57,11 @@ pub fn allocateZeroMemory(bytes: u64) ![]align(0x1000) u8 {
pub const ExecutionError = error{failed};
pub fn spawnProcess(arguments: []const []const u8, allocator: lib.ZigAllocator) !void {
var process = ChildProcess.init(arguments, allocator);
// std.log.err("Spawning process:", .{});
// for (arguments) |arg| {
// std.log.err("Arg: {s}", .{arg});
// }
process.stdout_behavior = .Ignore;
const execution_result = try process.spawnAndWait();

View File

@ -39,29 +39,29 @@ const MountedPartition = struct {
loopback_device: LoopbackDevice,
fn mkdir(partition: MountedPartition, allocator: lib.ZigAllocator, dir: []const u8) !void {
try host.spawnProcess(&.{ "sudo", "mkdir", "-p", try partition.join_with_root(allocator, dir) }, allocator);
try host.spawnProcess(&.{ "sudo", "mkdir", "-p", try partition.joinWithRoot(allocator, dir) }, allocator);
}
fn join_with_root(partition: MountedPartition, allocator: lib.ZigAllocator, path: []const u8) ![]const u8 {
const mount_dir = partition.get_mount_dir();
fn joinWithRoot(partition: MountedPartition, allocator: lib.ZigAllocator, path: []const u8) ![]const u8 {
const mount_dir = partition.getMountDir();
const slices_to_join: []const []const u8 = if (path[0] == '/') &.{ mount_dir, path } else &.{ mount_dir, "/", path };
const joint_path = try lib.concat(allocator, u8, slices_to_join);
return joint_path;
}
pub fn get_mount_dir(partition: MountedPartition) []const u8 {
const mount_dir = partition.loopback_device.mount_dir orelse @panic("get_mount_dir");
pub fn getMountDir(partition: MountedPartition) []const u8 {
const mount_dir = partition.loopback_device.mount_dir orelse @panic("getMountDir");
return mount_dir;
}
fn copy_file(partition: MountedPartition, allocator: lib.ZigAllocator, file_path: []const u8, file_content: []const u8) !void {
fn copyFile(partition: MountedPartition, allocator: lib.ZigAllocator, file_path: []const u8, file_content: []const u8) !void {
// TODO: make this work for Windows?
const last_slash_index = lib.lastIndexOf(u8, file_path, "/") orelse @panic("fat32: copy file last slash");
const file_name = host.basename(file_path);
assert(file_name.len > 0);
try host.cwd().writeFile(file_name, file_content);
const dir = file_path[0..if (last_slash_index == 0) 1 else last_slash_index];
const destination_dir = try partition.join_with_root(allocator, dir);
const destination_dir = try partition.joinWithRoot(allocator, dir);
const mkdir_process_args = &.{ "sudo", "mkdir", "-p", destination_dir };
try host.spawnProcess(mkdir_process_args, allocator);
const copy_process_args = &.{ "sudo", "cp", "-v", file_name, destination_dir };
@ -167,7 +167,7 @@ test "Limine barebones" {
}
for (limine_files) |file| {
try partition.copy_file(wrapped_allocator.zigUnwrap(), file.path, file.content);
try partition.copyFile(wrapped_allocator.zigUnwrap(), file.path, file.content);
}
try partition.end(wrapped_allocator.zigUnwrap());

View File

@ -22,8 +22,17 @@ const Error = error{
architecture_not_supported,
execution_environment_not_supported,
ovmf_path_not_found,
is_default_not_found,
};
const ParseBoolError = error{
not_found,
};
fn parseBool(argument: []const u8) !bool {
return if (lib.equal(u8, argument, "true")) true else if (lib.equal(u8, argument, "false")) false else ParseBoolError.not_found;
}
pub fn main() anyerror!void {
const max_file_length = lib.maxInt(usize);
var arena_allocator = host.ArenaAllocator.init(host.page_allocator);
@ -46,6 +55,7 @@ pub fn main() anyerror!void {
var argument_init_path: ?[]const u8 = null;
var argument_index: usize = 0;
var argument_ovmf_path: ?[]const u8 = null;
var argument_is_default: ?bool = null;
while (argument_parser.next()) |argument_type| switch (argument_type) {
.disk_image_path => {
@ -66,7 +76,7 @@ pub fn main() anyerror!void {
argument_qemu_options = undefined;
inline for (lib.fields(lib.QEMUOptions), 0..) |field, field_index| {
@field(argument_qemu_options.?, field.name) = if (lib.equal(u8, boolean_argument_strings[field_index], "true")) true else if (lib.equal(u8, boolean_argument_strings[field_index], "false")) false else return Error.qemu_options_not_found;
@field(argument_qemu_options.?, field.name) = parseBool(boolean_argument_strings[field_index]) catch return Error.qemu_options_not_found;
}
},
.configuration => {
@ -82,15 +92,15 @@ pub fn main() anyerror!void {
argument_index += 1;
},
.ci => {
argument_ci = if (lib.equal(u8, arguments[argument_index], "true")) true else if (lib.equal(u8, arguments[argument_index], "false")) false else return Error.ci_not_found;
argument_ci = parseBool(arguments[argument_index]) catch return Error.ci_not_found;
argument_index += 1;
},
.debug_user => {
argument_debug_user = if (lib.equal(u8, arguments[argument_index], "true")) true else if (lib.equal(u8, arguments[argument_index], "false")) false else return Error.debug_user_not_found;
argument_debug_user = parseBool(arguments[argument_index]) catch return Error.debug_user_not_found;
argument_index += 1;
},
.debug_loader => {
argument_debug_loader = if (lib.equal(u8, arguments[argument_index], "true")) true else if (lib.equal(u8, arguments[argument_index], "false")) false else return Error.debug_loader_not_found;
argument_debug_loader = parseBool(arguments[argument_index]) catch return Error.debug_loader_not_found;
argument_index += 1;
},
.init => {
@ -101,6 +111,10 @@ pub fn main() anyerror!void {
argument_ovmf_path = arguments[argument_index];
argument_index += 1;
},
.is_default => {
argument_is_default = parseBool(arguments[argument_index]) catch return Error.is_default_not_found;
argument_index += 1;
},
};
if (argument_index != arguments.len) return Error.wrong_argument_count;
@ -117,6 +131,7 @@ pub fn main() anyerror!void {
.debug_loader = argument_debug_loader orelse return Error.debug_loader_not_found,
.init = argument_init_path orelse return Error.init_not_found,
.ovmf_path = argument_ovmf_path orelse return Error.ovmf_path_not_found,
.is_default = argument_is_default orelse return Error.is_default_not_found,
};
};
@ -124,6 +139,21 @@ pub fn main() anyerror!void {
.qemu => {
const qemu_options = arguments_result.qemu_options;
const unique_base_name = blk: {
var list = host.ArrayList(u8).init(wrapped_allocator.zigUnwrap());
inline for (lib.fields(Configuration)) |conf_field| {
try list.appendSlice(@tagName(@field(arguments_result.configuration, conf_field.name)));
try list.append('_');
}
break :blk list.items;
};
const debugcon_file = try lib.concat(wrapped_allocator.zigUnwrap(), u8, &.{ "logs/", unique_base_name, "debugcon.log" });
const qemu_debug_file = try lib.concat(wrapped_allocator.zigUnwrap(), u8, &.{ "logs/", unique_base_name, "debug.log" });
var debugcon_file_used = false;
var qemu_debug_file_used = false;
const config_file = try host.cwd().readFileAlloc(wrapped_allocator.zigUnwrap(), "config/qemu.json", max_file_length);
const parsed_arguments = try lib.json.parseFromSlice(Arguments, wrapped_allocator.zigUnwrap(), config_file, .{});
const arguments = parsed_arguments.value;
@ -169,7 +199,12 @@ pub fn main() anyerror!void {
if (arguments.debugcon) |debugcon| {
try argument_list.append("-debugcon");
try argument_list.append(@tagName(debugcon));
if (arguments_result.is_default) {
try argument_list.append(@tagName(debugcon));
} else {
debugcon_file_used = true;
try argument_list.append(try lib.concat(wrapped_allocator.zigUnwrap(), u8, &.{ "file:", debugcon_file }));
}
}
if (arguments.memory) |memory| {
@ -213,30 +248,29 @@ pub fn main() anyerror!void {
}
}
if (!arguments_result.ci) {
if (arguments.log) |log_configuration| {
var log_what = host.ArrayList(u8).init(wrapped_allocator.zigUnwrap());
if (arguments.log) |log_configuration| {
var log_what = host.ArrayList(u8).init(wrapped_allocator.zigUnwrap());
if (log_configuration.guest_errors) try log_what.appendSlice("guest_errors,");
if (log_configuration.interrupts) try log_what.appendSlice("int,");
if (!arguments_result.ci and log_configuration.assembly) try log_what.appendSlice("in_asm,");
if (log_configuration.guest_errors) try log_what.appendSlice("guest_errors,");
if (log_configuration.interrupts) try log_what.appendSlice("int,");
if (!arguments_result.ci and log_configuration.assembly) try log_what.appendSlice("in_asm,");
if (log_what.items.len > 0) {
// Delete the last comma
_ = log_what.pop();
if (log_what.items.len > 0) {
// Delete the last comma
_ = log_what.pop();
try argument_list.append("-d");
try argument_list.append(log_what.items);
try argument_list.append("-d");
try argument_list.append(log_what.items);
if (log_configuration.interrupts) {
try argument_list.appendSlice(&.{ "-machine", "smm=off" });
}
if (log_configuration.interrupts) {
try argument_list.appendSlice(&.{ "-machine", "smm=off" });
}
}
if (log_configuration.file) |log_file| {
try argument_list.append("-D");
try argument_list.append(log_file);
}
if (!arguments_result.is_default) {
qemu_debug_file_used = true;
try argument_list.append("-D");
try argument_list.append(qemu_debug_file);
}
}
}
@ -298,6 +332,7 @@ pub fn main() anyerror!void {
}
var process = host.ChildProcess.init(argument_list.items, wrapped_allocator.zigUnwrap());
//process.stdout_behavior = .I;
const result = try process.spawnAndWait();
if (result == .Exited) {
@ -310,7 +345,9 @@ pub fn main() anyerror!void {
const qemu_exit_code = @as(lib.QEMU.ExitCode, @enumFromInt(masked_exit_code >> 1));
switch (qemu_exit_code) {
.success => return log.info("Success!", .{}),
.success => {
return;
},
.failure => log.err("QEMU exited with failure code 0x{x}", .{exit_code}),
_ => log.err("Totally unexpected value", .{}),
}
@ -320,6 +357,16 @@ pub fn main() anyerror!void {
log.err("QEMU was {s}", .{@tagName(result)});
}
if (debugcon_file_used) {
const debugcon_file_content = try host.cwd().readFileAlloc(wrapped_allocator.zigUnwrap(), debugcon_file, lib.maxInt(usize));
@import("std").debug.print("\n{s}\n", .{debugcon_file_content});
}
if (qemu_debug_file_used) {
const debug_file_content = try host.cwd().readFileAlloc(wrapped_allocator.zigUnwrap(), qemu_debug_file, lib.maxInt(usize));
@import("std").debug.print("\n{s}\n", .{debug_file_content});
}
return Error.qemu_error;
},
}
@ -348,7 +395,6 @@ const Arguments = struct {
stdio,
},
log: ?struct {
file: ?[]const u8,
guest_errors: bool,
assembly: bool,
interrupts: bool,

View File

@ -1,4 +1,4 @@
#!/bin/sh
# $1 Loopback device
set -e
sudo mkfs.fat -F 32 `cat $1`p1 1>2
sudo mkfs.fat -F 32 `cat $1`p1