Commit 9bf63b0996
Changed files (5)
src/link/Elf.zig
@@ -2453,18 +2453,23 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
const file_offset = self.sections.items(.shdr)[shdr_index].sh_offset + section_offset;
if (self.base.child_pid) |pid| {
- var code_vec: [1]std.os.iovec_const = .{.{
- .iov_base = code.ptr,
- .iov_len = code.len,
- }};
- var remote_vec: [1]std.os.iovec_const = .{.{
- .iov_base = @intToPtr([*]u8, local_sym.st_value),
- .iov_len = code.len,
- }};
- const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0);
- switch (std.os.errno(rc)) {
- .SUCCESS => assert(rc == code.len),
- else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
+ switch (builtin.os.tag) {
+ .linux => {
+ var code_vec: [1]std.os.iovec_const = .{.{
+ .iov_base = code.ptr,
+ .iov_len = code.len,
+ }};
+ var remote_vec: [1]std.os.iovec_const = .{.{
+ .iov_base = @intToPtr([*]u8, local_sym.st_value),
+ .iov_len = code.len,
+ }};
+ const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0);
+ switch (std.os.errno(rc)) {
+ .SUCCESS => assert(rc == code.len),
+ else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
+ }
+ },
+ else => return error.HotSwapUnavailableOnHostOperatingSystem,
}
}
@@ -2856,18 +2861,23 @@ fn writeOffsetTableEntry(self: *Elf, index: usize) !void {
try self.base.file.?.pwriteAll(&buf, off);
if (self.base.child_pid) |pid| {
- var local_vec: [1]std.os.iovec_const = .{.{
- .iov_base = &buf,
- .iov_len = buf.len,
- }};
- var remote_vec: [1]std.os.iovec_const = .{.{
- .iov_base = @intToPtr([*]u8, vaddr),
- .iov_len = buf.len,
- }};
- const rc = std.os.linux.process_vm_writev(pid, &local_vec, &remote_vec, 0);
- switch (std.os.errno(rc)) {
- .SUCCESS => assert(rc == buf.len),
- else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
+ switch (builtin.os.tag) {
+ .linux => {
+ var local_vec: [1]std.os.iovec_const = .{.{
+ .iov_base = &buf,
+ .iov_len = buf.len,
+ }};
+ var remote_vec: [1]std.os.iovec_const = .{.{
+ .iov_base = @intToPtr([*]u8, vaddr),
+ .iov_len = buf.len,
+ }};
+ const rc = std.os.linux.process_vm_writev(pid, &local_vec, &remote_vec, 0);
+ switch (std.os.errno(rc)) {
+ .SUCCESS => assert(rc == buf.len),
+ else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
+ }
+ },
+ else => return error.HotSwapUnavailableOnHostOperatingSystem,
}
}
},
src/Compilation.zig
@@ -1847,7 +1847,7 @@ fn cleanupTmpArtifactDirectory(
}
}
-pub fn hotCodeSwap(comp: *Compilation, prog_node: *std.Progress.Node, pid: std.os.pid_t) !void {
+pub fn hotCodeSwap(comp: *Compilation, prog_node: *std.Progress.Node, pid: std.ChildProcess.Id) !void {
comp.bin_file.child_pid = pid;
try comp.makeBinFileWritable();
try comp.update(prog_node);
src/link.zig
@@ -264,7 +264,7 @@ pub const File = struct {
/// of this linking operation.
lock: ?Cache.Lock = null,
- child_pid: ?std.os.pid_t = null,
+ child_pid: ?std.ChildProcess.Id = null,
/// Attempts incremental linking, if the file already exists. If
/// incremental linking fails, falls back to truncating the file and
@@ -388,10 +388,14 @@ pub const File = struct {
});
try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{});
try emit.directory.handle.rename(tmp_sub_path, emit.sub_path);
-
- switch (std.os.errno(std.os.linux.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0, 0))) {
- .SUCCESS => {},
- else => |errno| log.warn("ptrace failure: {s}", .{@tagName(errno)}),
+ switch (builtin.os.tag) {
+ .linux => {
+ switch (std.os.errno(std.os.linux.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0, 0))) {
+ .SUCCESS => {},
+ else => |errno| log.warn("ptrace failure: {s}", .{@tagName(errno)}),
+ }
+ },
+ else => return error.HotSwapUnavailableOnHostOperatingSystem,
}
}
base.file = try emit.directory.handle.createFile(emit.sub_path, .{
@@ -444,9 +448,14 @@ pub const File = struct {
base.file = null;
if (base.child_pid) |pid| {
- switch (std.os.errno(std.os.linux.ptrace(std.os.linux.PTRACE.DETACH, pid, 0, 0, 0))) {
- .SUCCESS => {},
- else => |errno| log.warn("ptrace failure: {s}", .{@tagName(errno)}),
+ switch (builtin.os.tag) {
+ .linux => {
+ switch (std.os.errno(std.os.linux.ptrace(std.os.linux.PTRACE.DETACH, pid, 0, 0, 0))) {
+ .SUCCESS => {},
+ else => |errno| log.warn("ptrace failure: {s}", .{@tagName(errno)}),
+ }
+ },
+ else => return error.HotSwapUnavailableOnHostOperatingSystem,
}
}
},
@@ -487,6 +496,7 @@ pub const File = struct {
NetNameDeleted,
DeviceBusy,
InvalidArgument,
+ HotSwapUnavailableOnHostOperatingSystem,
};
/// Called from within the CodeGen to lower a local variable instantion as an unnamed
src/main.zig
@@ -3534,7 +3534,7 @@ fn serve(
try serveStringMessage(out, .zig_version, build_options.version);
- var child_pid: ?i32 = null;
+ var child_pid: ?std.ChildProcess.Id = null;
var receive_fifo = std.fifo.LinearFifo(u8, .Dynamic).init(gpa);
defer receive_fifo.deinit();
@@ -3978,7 +3978,7 @@ fn runOrTestHotSwap(
arg_mode: ArgMode,
all_args: []const []const u8,
runtime_args_start: ?usize,
-) !i32 {
+) !std.ChildProcess.Id {
const exe_emit = comp.bin_file.options.emit.?;
// A naive `directory.join` here will indeed get the correct path to the binary,
// however, in the case of cwd, we actually want `./foo` so that the path can be executed.
@@ -4023,7 +4023,7 @@ fn runOrTestHotSwap(
try child.spawn();
- return child.pid;
+ return child.id;
}
const AfterUpdateHook = union(enum) {
src/test.zig
@@ -1606,9 +1606,8 @@ pub const TestContext = struct {
var module_node = update_node.start("parse/analysis/codegen", 0);
module_node.activate();
- module_node.context.refresh();
try comp.makeBinFileWritable();
- try comp.update();
+ try comp.update(&module_node);
module_node.end();
if (update.case != .Error) {