log: fix log issue which hurt console badly
This commit is contained in:
parent
820e60a506
commit
2500b78896
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ bochsout.txt
|
||||
*.hdd
|
||||
loopback_device
|
||||
tools/OVMF.fd
|
||||
logs/*.log
|
||||
|
@ -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;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"architecture": "x86_64",
|
||||
"bootloader": "birth",
|
||||
"bootloader": "limine",
|
||||
"boot_protocol": "uefi",
|
||||
"execution_environment": "qemu",
|
||||
"optimize_mode": "Debug",
|
||||
|
@ -8,7 +8,6 @@
|
||||
"smp": 2,
|
||||
"debugcon": "stdio",
|
||||
"log": {
|
||||
"file": null,
|
||||
"guest_errors": true,
|
||||
"assembly": false,
|
||||
"interrupts": true
|
||||
|
0
logs/.gitkeep
Normal file
0
logs/.gitkeep
Normal 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,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user