From b4c560d4b8a3d0baf2cc941e5ff85e9b1ea6beef Mon Sep 17 00:00:00 2001 From: Bastian Buck <59334447+bstnbuck@users.noreply.github.com> Date: Sat, 25 May 2024 23:46:43 +0200 Subject: [PATCH] os: fix debugger_present() for non Windows OSes (#21573) --- vlib/os/debugger_darwin.c.v | 32 ++++++++++++++++++++++++++++---- vlib/os/debugger_freebsd.c.v | 32 ++++++++++++++++++++++++++++---- vlib/os/debugger_linux.c.v | 32 ++++++++++++++++++++++++++++---- 3 files changed, 84 insertions(+), 12 deletions(-) diff --git a/vlib/os/debugger_darwin.c.v b/vlib/os/debugger_darwin.c.v index 0a0f8f7ee5..44dd22c481 100644 --- a/vlib/os/debugger_darwin.c.v +++ b/vlib/os/debugger_darwin.c.v @@ -6,12 +6,36 @@ module os fn C.ptrace(int, u32, voidptr, int) int // debugger_present returns a bool indicating if the process is being debugged -@[inline] pub fn debugger_present() bool { - // check if the parent could trace its process, - // if not a debugger must be present $if macos { - return C.ptrace(C.PT_TRACE_ME, 0, voidptr(1), 0) == -1 + // check if a child process could trace its parent process, + // if not a debugger must be present + pid := fork() + if pid == 0 { + ppid := getppid() + if C.ptrace(C.PT_TRACE_ME, ppid, unsafe { nil }, 0) == 0 { + C.waitpid(ppid, 0, 0) + + // detach ptrace, otherwise further checks would indicate a debugger is present (ptrace is the Debugger then) + C.ptrace(C.PT_DETACH, ppid, 0, 0) + + // no external debugger + exit(0) + } else { + // an error occured, a external debugger must be present + exit(1) + } + } else { + mut status := 0 + // wait until the child process dies + C.waitpid(pid, &status, 0) + // check the exit code of the child process check + if C.WEXITSTATUS(status) == 0 { + return false + } else { + return true + } + } } return false } diff --git a/vlib/os/debugger_freebsd.c.v b/vlib/os/debugger_freebsd.c.v index 2e61d25b5f..60232c9207 100644 --- a/vlib/os/debugger_freebsd.c.v +++ b/vlib/os/debugger_freebsd.c.v @@ -5,12 +5,36 @@ module os fn C.ptrace(int, u32, voidptr, int) int // debugger_present returns a bool indicating if the process is being debugged -@[inline] pub fn debugger_present() bool { - // check if the parent could trace its process, - // if not a debugger must be present $if freebsd { - return C.ptrace(C.PT_TRACE_ME, 0, voidptr(1), 0) == -1 + // check if a child process could trace its parent process, + // if not a debugger must be present + pid := fork() + if pid == 0 { + ppid := getppid() + if C.ptrace(C.PT_TRACE_ME, ppid, unsafe { nil }, 0) == 0 { + C.waitpid(ppid, 0, 0) + + // detach ptrace, otherwise further checks would indicate a debugger is present (ptrace is the Debugger then) + C.ptrace(C.PT_DETACH, ppid, 0, 0) + + // no external debugger + exit(0) + } else { + // an error occured, a external debugger must be present + exit(1) + } + } else { + mut status := 0 + // wait until the child process dies + C.waitpid(pid, &status, 0) + // check the exit code of the child process check + if C.WEXITSTATUS(status) == 0 { + return false + } else { + return true + } + } } return false } diff --git a/vlib/os/debugger_linux.c.v b/vlib/os/debugger_linux.c.v index 90ea3fdc19..63f75e369a 100644 --- a/vlib/os/debugger_linux.c.v +++ b/vlib/os/debugger_linux.c.v @@ -5,16 +5,40 @@ module os fn C.ptrace(u32, u32, voidptr, voidptr) u64 // debugger_present returns a bool indicating if the process is being debugged -@[inline] pub fn debugger_present() bool { $if cross ? { return false } $if !cross ? { - // check if the parent could trace its process, - // if not a debugger must be present $if linux { - return C.ptrace(C.PTRACE_TRACEME, 0, 1, 0) == -1 + // check if a child process could trace its parent process, + // if not a debugger must be present + pid := fork() + if pid == 0 { + ppid := getppid() + if C.ptrace(C.PTRACE_ATTACH, ppid, 0, 0) == 0 { + C.waitpid(ppid, 0, 0) + + // detach ptrace, otherwise further checks would indicate a debugger is present (ptrace is the Debugger then) + C.ptrace(C.PTRACE_DETACH, ppid, 0, 0) + + // no external debugger + exit(0) + } else { + // an error occured, a external debugger must be present + exit(1) + } + } else { + mut status := 0 + // wait until the child process dies + C.waitpid(pid, &status, 0) + // check the exit code of the child process check + if C.WEXITSTATUS(status) == 0 { + return false + } else { + return true + } + } } } return false