diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index 3f768b5d4c..b68f04379f 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -102,6 +102,8 @@ pub const MACH_EXCEPTION_MASK = MACH_EXCEPTION_CODES | pub const TASK_NULL: task_t = 0; pub const THREAD_NULL: thread_t = 0; +pub const MACH_PORT_NULL: mach_port_t = 0; +pub const MACH_MSG_TIMEOUT_NONE: mach_msg_timeout_t = 0; pub const MACH_MSG_OPTION_NONE = 0x00000000; @@ -406,6 +408,7 @@ pub extern "c" fn task_resume(target_task: task_read_t) kern_return_t; pub extern "c" fn task_suspend(target_task: task_read_t) kern_return_t; pub extern "c" fn task_for_pid(target_tport: mach_port_name_t, pid: pid_t, t: *mach_port_name_t) kern_return_t; +pub extern "c" fn pid_for_task(target_tport: mach_port_name_t, pid: *pid_t) kern_return_t; pub extern "c" fn mach_vm_read( target_task: vm_map_read_t, address: mach_vm_address_t, @@ -3054,11 +3057,20 @@ pub const _POSIX_SPAWN_RESLIDE = 0x0800; pub const POSIX_SPAWN_CLOEXEC_DEFAULT = 0x4000; pub const PT_TRACE_ME = 0; +pub const PT_READ_I = 1; +pub const PT_READ_D = 2; +pub const PT_READ_U = 3; +pub const PT_WRITE_I = 4; +pub const PT_WRITE_D = 5; +pub const PT_WRITE_U = 6; pub const PT_CONTINUE = 7; pub const PT_KILL = 8; pub const PT_STEP = 9; pub const PT_DETACH = 11; +pub const PT_SIGEXC = 12; +pub const PT_THUPDATE = 13; pub const PT_ATTACHEXC = 14; +pub const PT_FORCEQUOTA = 30; pub const PT_DENY_ATTACH = 31; pub const caddr_t = ?[*]u8; diff --git a/lib/std/os/darwin.zig b/lib/std/os/darwin.zig index 161d0138f0..b3fb681d5a 100644 --- a/lib/std/os/darwin.zig +++ b/lib/std/os/darwin.zig @@ -24,6 +24,18 @@ const mach_task = if (builtin.target.isDarwin()) struct { return self.port != std.c.TASK_NULL; } + pub fn pidForTask(self: MachTask) MachError!std.os.pid_t { + var pid: std.os.pid_t = undefined; + switch (std.c.getKernError(std.c.pid_for_task(self.port, &pid))) { + .SUCCESS => return pid, + .FAILURE => return error.PermissionDenied, + else => |err| { + log.err("pid_for_task kernel call failed with error code: {s}", .{@tagName(err)}); + return error.Unexpected; + }, + } + } + pub fn allocatePort(self: MachTask, right: std.c.MACH_PORT_RIGHT) MachError!MachTask { var out_port: std.c.mach_port_name_t = undefined; switch (std.c.getKernError(std.c.mach_port_allocate( @@ -440,7 +452,7 @@ const mach_task = if (builtin.target.isDarwin()) struct { } const ThreadList = struct { - buf: []ThreadId, + buf: []MachThread, pub fn deinit(list: ThreadList) void { const self_task = machTaskForSelf(); @@ -456,7 +468,7 @@ const mach_task = if (builtin.target.isDarwin()) struct { var thread_list: std.c.mach_port_array_t = undefined; var thread_count: std.c.mach_msg_type_number_t = undefined; switch (std.c.getKernError(std.c.task_threads(task.port, &thread_list, &thread_count))) { - .SUCCESS => return ThreadList{ .buf = @ptrCast([*]ThreadId, thread_list)[0..thread_count] }, + .SUCCESS => return ThreadList{ .buf = @ptrCast([*]MachThread, thread_list)[0..thread_count] }, else => |err| { log.err("task_threads kernel call failed with error code: {s}", .{@tagName(err)}); return error.Unexpected; @@ -465,14 +477,18 @@ const mach_task = if (builtin.target.isDarwin()) struct { } }; - pub const ThreadId = extern struct { - id: std.c.thread_act_t, + pub const MachThread = extern struct { + port: std.c.mach_port_t, - pub fn getBasicInfo(thread_id: ThreadId) MachError!std.c.thread_basic_info { + pub fn isValid(thread: MachThread) bool { + return thread.port != std.c.THREAD_NULL; + } + + pub fn getBasicInfo(thread: MachThread) MachError!std.c.thread_basic_info { var info: std.c.thread_basic_info = undefined; var count = std.c.THREAD_BASIC_INFO_COUNT; switch (std.c.getKernError(std.c.thread_info( - thread_id.id, + thread.port, std.c.THREAD_BASIC_INFO, @ptrCast(std.c.thread_info_t, &info), &count, @@ -485,11 +501,11 @@ const mach_task = if (builtin.target.isDarwin()) struct { } } - pub fn getIdentifierInfo(thread_id: ThreadId) MachError!std.c.thread_identifier_info { + pub fn getIdentifierInfo(thread: MachThread) MachError!std.c.thread_identifier_info { var info: std.c.thread_identifier_info = undefined; var count = std.c.THREAD_IDENTIFIER_INFO_COUNT; switch (std.c.getKernError(std.c.thread_info( - thread_id.id, + thread.port, std.c.THREAD_IDENTIFIER_INFO, @ptrCast(std.c.thread_info_t, &info), &count, diff --git a/lib/std/os/ptrace.zig b/lib/std/os/ptrace.zig index 4168ed0032..afe0b51e2e 100644 --- a/lib/std/os/ptrace.zig +++ b/lib/std/os/ptrace.zig @@ -16,8 +16,8 @@ const ptrace = if (builtin.target.isDarwin()) struct { PermissionDenied, } || UnexpectedError; - pub fn ptrace(request: i32, pid: pid_t) PtraceError!void { - switch (errno(system.ptrace(request, pid, null, 0))) { + pub fn ptrace(request: i32, pid: pid_t, addr: ?[*]u8, signal: i32) PtraceError!void { + switch (errno(system.ptrace(request, pid, addr, signal))) { .SUCCESS => return, .SRCH => return error.ProcessNotFound, .INVAL => unreachable,